大家都知道,对付简单的反爬虫有这么几种方式,随机请求头User-Agent,限流器,还有就是,使用不同的ip进行爬取,等等,,,
网上也有比较多的代理IP,本文章用的是西刺代理,当然其他的代理ip也是可以的,看个人喜好吧,既然有了代理,那么怎么获取里面的ip为自己所用,这又是要写一个脚本文件。
当然你也可以从网址上复制几个下来,然后随机一下,但是这不是刚学的爬虫吗,总要好好的利用起来。
废话不多说,开始吧,
啊,注意啊,西刺代理挂了,也就是说后面这些代码完全没用了,只能参考看看,自己找其他的代理吧!!!
首先我们要爬取西刺代理(https://www.xicidaili.com/nn/)
程序员都知道,只要这几行代码是一个功能,与上下文耦合度不高,那就可以单独拿出来放进一个函数或类里面,所以本文章就是封装了好多函数,本文章解析的是一个网页的ip(就是西刺的第一页),有100个,差不多够用
导的包以及初始化
import random
import requests
from fake_useragent import UserAgent # 随机User-Agent
from retrying import retry # 重试下载
import lxml.html # 用来解析网页
class ReptileIp(object):
def __init__(self,init_url):
__ua = UserAgent()
self.init_url = init_url # 网页地址
self.headers = {'User-Agent':__ua.random}
获取网页内容
# 下载重试
@retry(stop_max_attempt_number = 3) # 这个装饰器就是用来重试下载的 重试3次
def download_html(self,url_str,data,method,proxies):
if method == 'POST': # 判断请求方式
result = requests.post(url_str,data=data,headers=self.headers,proxies=proxies)
else:
result = requests.get(url_str,headers=self.headers,timeout = 3,proxies=proxies)
assert result.status_code == 200 # 断言,状态码不等于200说明失败了,重试下载
return result.content # 返回网页HTML,字节流
#下载内容
def download_url(self,url_str,data=None,method = 'GET',proxies = {}):
# 这里要捕获异常,请求网页出现错误在这里可以捕获到
try:
# 调用上面的写好的 重试下载download_html()
result = self.download_html(url_str,data,method,proxies)
except Exception as e:
print(e)
result = None
return result
解析网页HTML,提取ip
这个就是网页的部分代码,箭头标记的就是要捕获的内容,
解析HTML的代码
# 提取信息
def filter_html(self,content):
html = lxml.html.fromstring(content)
data_host = html.xpath('//table/tr/td[last()-8]/text()') # ip
data_port = html.xpath('//table/tr/td[last()-7]/text()') # 端口号
data_http = html.xpath('//table/tr/td[last()-4]/text()') # http/https
proxies = [] # 存放拼接好的ip地址
for num in len(data_http):
http = data_http[num]
host = data_host[num] # ip 60.216.101.46
port = data_port[num] # 端口号 59351
https = http + '://' + host + ':' + port # 拼接
proxies.append(https) # 添加进list
return proxies
主要的逻辑函数
def run(self):
url_str = self.init_url # url,
# 下载链接
html_content = self.download_url(url_str) # 调用上面的下载
# 提取ip 得到的是列表,转成字符串用!分割每个ip,方便后续读取解析
proxies_list = '!'.join(self.filter_html(html_content)) # 调用上面的提取ip
with open('ip.txt','w+') as fp: # 保存进txt文件
fp.write(proxies_list)
校验ip是否可用
因为用的是免费的代理ip,所以有的ip地址不一定能用,要校验一下
# 校验ip
def verify_ip(self):
with open('ip.txt','r') as fp: # 读取文件里的ip
proxies_list = fp.read()
proxies_list = proxies_list.split('!') # 还记得存的是字符串,用!切割成列表
p_list = random.sample(proxies_list,4) # 因为里面有100个ip校验起来比较慢,所以随机抽取4个,进行校验
invalid_ip = [] # 存放失效的ip
for url in p_list:
proxies = {'http': url}
# 这里通过访问百度的页面进行校验
req = requests.get('https://www.baidu.com', headers=self.headers, proxies=proxies)
if req.status_code == 200: # 状态码是200,说明此ip能用
continue
else:
invalid_ip.append(url) # 否则,存进要删除的列表中
for i in invalid_ip:
proxies_list.remove(i) # 删除失效的ip
return {'http': random.choice(proxies_list)} # 随机返回一个能用的ip
执行程序
if __name__ == '__main__':
ip = ReptileIp('https://www.xicidaili.com/nn/2')
# 获取 run()执行一次就可以了,
# ip.run()
# 校验,并取1个ip
print(ip.verify_ip()) #
因为我们把100个ip存进了文档,够用一段时间,也可以自己写个函数,让它自己每个一段时间更新一下文档里的ip,切记不要一直不断地运行,持续不断的访问会导致西刺封禁自己的ip。
用此代理IP时,可以把run()放在if name == ‘main’:下,校验ip 函数verify_ip() 放在自己的爬虫代码里,这样运行一次爬虫代码就会更新100个ip,
在这一篇博客中有用到上面的代理ip的代码,有兴趣的可以看一下CSDN博客刷阅读数脚本,
,