文章目录
- 前言
- 简介
- 代码
- 如何调用结果
- 总结
前言
常见的反爬虫措施之一,就是查看用户发起请求的IP地址,若很频繁,则封IP。我们可以通过使用动态代理IP池实现反爬虫。百度搜索:爬虫IP池, 就有很多网站,这些网站一般都有提供免费的代理IP。但是这些IP质量不高,需要自己手动复制粘贴,测试后再使用,效率底下。我们可以写个爬虫,批量获取免费IP,自动测试后,再使用。
简介
传入URL地址,返回可用的IP地址list列表。
- __init __ :设置请求头、请求地址list
- parse : 获得当前页面上的所有IP和端口号,返回一个list
- check_ip : 检查IP地址是否可用,返回可用的当前页面上的IP地址list和端口号
- get_ip : 运行主方法,返回所有可用的IP列表
- main : 主方法,最后会打印出符合条件的IP地址+端口号,读者可手动复制控制台上的信息,作为自己的IP代理池
代码
import requests
from lxml import etree
class FreeIp():
def __init__(self):
self.start_url = "https://ip.jiangxianli.com/?page={}"
self.url_list = [self.start_url.format(i) for i in range(1, 6)] # 这里可以按实际情况更改
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"}
def parse(self, html):
tr_list = html.xpath("//table[@class='layui-table']/tbody/tr")
ip_list = []
for tr in tr_list:
if tr.xpath("./td/text()")[2] == "高匿" and tr.xpath("./td/text()")[3] == "HTTP":
ip = {}
ip["ip"] = tr.xpath("./td/text()")[0]
ip["port"] = tr.xpath("./td/text()")[1]
ip_list.append(ip)
return ip_list
def check_ip(self, ip_list):
correct_ip = []
for ip in ip_list:
ip_port = ip["ip"] + ":" + ip["port"]
proxies = {'http': ip_port}
try:
response = requests.get('http://icanhazip.com/', proxies=proxies,
timeout=5).text
if response.strip() == ip["ip"]: # 如果请求该网址,返回的IP地址与代理IP一致,则认为代理成功
print("可用的IP地址为:{}".format(ip_port))
correct_ip.append(ip_port)
except:
print("不可用的IP地址为:{}".format(ip_port))
return correct_ip
def get_ip(self):
# 获得URL地址
correct_all_ip = []
for url in self.url_list:
# 获得请求,
response = requests.get(url, headers=self.headers).content.decode()
# 解析页面
html = etree.HTML(response)
# 得到IP
ip_list = self.parse(html)
# 检查IP
correct_ip = self.check_ip(ip_list)
correct_all_ip.extend(correct_ip)
# 返回所有IP
return correct_all_ip
if __name__ == '__main__':
free_ip = FreeIp()
ip = free_ip.get_ip()
print(ip)
print(len(ip))
如何调用结果
- (不推荐)可以将此代码复制到自己的爬虫代码里,每次调用free_ip.get_ip(),获得list。该方法不推荐,因为会使网站并发量大,并且小型爬虫项目不需要这么多代理IP。
- (推荐)手动复制控制台里的IP地址信息,粘贴到代码中,作为初始化IP地址,然后每次随机选择一个IP地址请求。
url = 'http://icanhazip.com/'
# 注意,底下的[]内容为复制粘贴上的
ip = ['191.101.39.238:80', '51.83.193.220:80', '104.43.230.151:3128', '123.56.239.196:3128', '113.214.13.1:1080', '116.117.134.135:80', '113.214.13.1:1080', '116.117.134.135:80', '183.47.237.251:80', '35.216.82.226:3128', '221.182.31.54:8080', '39.106.223.134:80', '124.48.218.245:80', '124.48.218.245:80', '62.171.144.29:3128', '159.203.44.177:3128', '120.232.150.100:80']
for i in range(100):
try:
real_ip = random.choice(ip)
proxy = {'http':real_ip}
res_text = requests.get(url=url,proxies=proxy, timeout = 3)
print("成功")
except:
print("{}不可用".format(real_ip))
ip.remove(real_ip)
总结
- 该网站基本上都是HTTP的IP地址,所以请求的url也只能为http网址。如果是HTTPS端口号,可以请求http、https网址
- 有的同学设置请求的时候,发现在设置proxy时,如果为http,而目标url为https,也能请求成功。这是误区,因为如果proxy里的类型和url类型不同时,请求的IP地址并不是代理IP地址,而是本机的IP,具体可以通过IP地址网站实验
- 网站可以在github上找到,ProxyIpLib。他提供了一个返回json的请求接口,我们也可以通过单个IP地址,多个IP地址 获得json响应,但是里面的IP地址不多,而且网页本身也不复杂,当作一个爬虫练手的小项目也行。