爬虫代理

前言

花了几天时间写了一个比较完整的爬虫代理模块,基本上实现了一个比较完整的代理系统。

有如下几大模块:

  • ip的获取模块
  • 检验及删除更新
  • requests循环请求

ip的获取

ip来源:http://www.xicidaili.com/wt/
通过遍历西刺代理中的四个页面获取ip,然后对ip有效性进行检验,将有效的ip写入文件。这里需要注意一下,西刺代理有效的ip一般都在前面,后面基本都是失效了的,我选择每个页面的前30条ip地址来检验,后面的直接舍弃。

	#http://www.xicidaili.com/wt/
	def get_goubanjia(self,url_target):
		try:
			#设置headers
			headers = {'User-Agent':str(UserAgent().random)}
			#发送requests请求
			req = requests.get(url_target,headers=headers, timeout=5)
			#校正网页编码
			req.encoding = req.apparent_encoding
			#对网页进行解析
			soup = BeautifulSoup(req.text, 'lxml')
			tr_list = soup.find_all('tr')

			for each in range(1, 31):
				print('已经筛选了{}条ip'.format(each))
				print("获取地址")
				#获取地址
				td = tr_list[each].find_all('td')
				a = td[1].get_text()
				print("获取端口")
				#获取端口
				b = td[2].get_text()
				#将有效的ip写入文件
				proxy = 'http://' + a+':'+b
				#检验ip是否有效,将有效的ip写入文件当中
				if self.verifyIP(proxy):
					f = open('ip.txt','a+',encoding='utf-8')
					f.write(proxy+'\n')
					f.close()
				#输出爬取到的信息
				print(proxy)
		except Exception as e:
			print(str(e))
			print('{}:网站页面发生变动,请及时更新'.format(url_target))

ip的检验

通过传入的proxy(‘http://123.123.123’),利用需要爬取的网站作为目标网站,发送requests请求来实现ip有效性的检验。
在检验ip有效性的过程中,我发现了这样一个有趣的现象,同一批ip对不同网站的访问速度不同(排除了网站本身的访问速度原因)。打个比方,有A、B两个网站他们的服务器配置是一样的,但是a、b、c、d四个ip从发送请求到相应这中间的时间却是不一样的。
所以,建议检验ip有效性时采用目标网站比较合适

	#验证ip,返回True/False值
	def verifyIP(self,proxy):
		print('开始判断{}的有效性'.format(proxy))
		try:
			#设置ip
			proxies = {'{}'.format(self.ip_stype):proxy}
			#设置headers
			headers = {'User-Agent':str(UserAgent().random)}
			#发生requests请求
			req = requests.get(self.url, headers=headers, proxies=proxies, verify=False, timeout=(6,14))
		except Exception as e:
			print('{}代理ip无效'.format(proxies))
			print('在检验过程中遇到的requests错误原因是:{}'.format(e))
			return False
		else:
			print('{}代理ip有效'.format(proxies))
			return True
		finally:
			print('{}代理ip有效性判断完成'.format(proxies))

删除ip

删除ip这块相对而言简单一些,读取文件–>删除旧文件–>删除ip列表中的失效ip–>将ip列表写入文件。

	#删除proxy
	def deleteProxy(self,proxy):
		print('删除无效proxy:{}'.format(proxy))
		f = open('ip.txt', 'r', encoding='utf-8')
		proxy_list = f.readlines()
		f.close()
		#删除列表中的换行符号
		proxy_list = [proxy.replace('\n','') for proxy in proxy_list]
		#删除原文件
		os.remove('ip.txt')
		#删除指定的proxy
		proxy_list.remove(proxy)
		#当文件为空时,重新下载文件
		if len(proxy_list)==0:
			print('现在列表为空,我们将重新获取ip')
			#调用父类下载新的ip文件
			super().getIpFile()
		#将信息重新写入文件
		f = open('ip.txt', 'a+', encoding='utf-8')
		for each in proxy_list:
			f.write(each+'\n')
		f.close()

ip文件的自动更新机制

简单点来说就是在删除失效ip后检测文件是否为空,为空时,再次从互联网上下载一批新的ip

	#删除指定的proxy
	proxy_list.remove(proxy)
	#当文件为空时,重新下载文件
	if len(proxy_list)==0:
		print('现在列表为空,我们将重新获取ip')
		#调用父类下载新的ip文件
		super().getIpFile()

requests循环请求

利用while构造一个死循环,只有在requests请求成功时,打破死循环的代码(flag=False)才会被执行,当然每一次循环都会采用新的IP地址以及headers

flag=True
while (flag!=False):
	try:
		try:
			#设置代理ip
			proxy = self.createRandomIp()
			#设置proxies
			proxies = {'{}'.format(self.ip_stype):proxy}
			#设置代理headers
			headers = {'User-Agent':str(UserAgent().random)}
			req = requests.get(self.url, proxies=proxies, headers=headers, verify=False, timeout=(9,21))
			flag=False
		except Exception as e:
			print('上一次请求失败,10秒后我们将进行下一次请求')
			print("上一次requests请求失败的原因是{}".format(e))
			print('上一次请求的代理ip为:{}'.format(proxy))
			time.sleep(10)
			#验证proxy的有效性,并对无效proxy进行处理
			proxy = self.verifyProxy(proxy)
			#设置proxies
			proxies = {'{}'.format(self.ip_stype):proxy}
			#设置代理headers
			headers = {'User-Agent':str(UserAgent().random)}
			req = requests.get(self.url, proxies=proxies, headers=headers, verify=False, timeout=(9,21))
			flag=False
	except:
		pass

备注

考虑到短时间多次访问一个网站可能会被识别出来,故在第一次发送requests请求时是不检验ip的有效性,如果请求出错则10秒后会对该ip进行验证,中间间隔10秒是考虑到网络信号的影响。如果检验到ip失效则会将其从ip文件中删除。

在删除失效ip后,会重新分配一个ip并对其有效性进行检验,无效则删除,重新分配ip直至分配的ip通过检验,采用的是递归算法。

在requests请求这一块,也具有相同的思想,不断发送requests请求直至成功,采用while构造死循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K同学啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值