低成本解决因ip被禁导致的爬虫程序中断

一、问题描述

网站的反爬措施越来越严格,各种反反爬措施也不断发展,最有效的反爬措施无异于是通过代理ip池的方法。

但是对于学习者或者数据量并不大的同学来说,购买或者维护一个ip池的成本并不低。

由此产生了一个想法,作为迫不得已的代替方法。

二、解决思路

现在宽带拨号使用的都是动态ip,每次重新拨号,就可以获得一个新的ip,这样就可以勉强解决上述问题。

头铁的解决思路

  • 将要爬取的链接用列表进行存储,
  • 然后大概判断一下几次请求之后就会被封掉(如:单个ip只能连续爬取20次)
  • 然后以20个为一组,将列表进行拆分,并保存成新的文件,这样就获得了若干个文件
  • 每次爬取一个文件之后,重新拨号获取新ip,然后进行重复爬取工作

存在的问题:

这样做太麻烦了,跟手工爬取没啥两样了,且重复性动作太多,文件数量也多,容易出错。

改进之后的思路:

  • 将请求列表保存到文件中
  • 读取请求列表文件,重新恢复成列表
  • 读取索引文件,获得已爬取的数据
  • 按照列表索引进行请求数据
    • 如果列表url已经爬取过,则跳过
    • 如果程序运行中断,则将已爬取的索引字典进行重新保存
  • 重新拨号,继续爬取

伪代码如下:

import requests

class Content:
	def __init__(self):
		self.url_list = []  # 存放已经爬取过的url  用字典存取也可以,效率更高。

	def clear(self):
		with open("索引url", mode="r") as f:  # 将已经爬取过的url进行存储
			for line in f:
				url = line.strip()
				self.url_list.append(url)

		with open("索引url", mode="a") as f:
			with open("url列表文件", mode='r') as fr:
				for line in fr:
					url = line.strip()

					if url not in self.url_list:  # 判断是否已经被爬取过

						try:
							status_code = self.download_url(url)
							if status_code == 1:  # 判断爬取状态
								f.write(url)
								f.write('\n')
							else:
								break

						except Exception as e:
							print(e)
							break

	def download_url(self, url):
		resp = requests.get(url)
		resp.encoding = "utf-8"  # 这里根据网页编码进行处理

		if "百度安全验证" in resp.text:  # 以百度贴吧为例,爬取次数过多会提示安全验证
			resp.close()
			print("爬取次数过多,请更换ip")
			return 1
		else:
			print(resp.text)  # 输出或者保存结果
			resp.close()
			return 0


if __name__ == "__main__":
	c = Content()
	c.clear()

三、后记

这是我根据增量式爬虫,利用redis数据库的去重功能,自己琢磨的一个笨办法,也是无奈之举。ip代理一直不成功,难办的很。

  • 一开始是用计数的方式进行的,但是这种计数的方法特别繁琐,且不能适用于异步协程
  • 现在利用json进行保存,就会显得比较简单且不用频繁读取文件,并能够适用到异步协程

依然存在的问题:

  • 如果某几个url一直无法爬取,则到最后一直重复运行程序但未能产生有效数据(可以尝试增加爬取次数信息,通过爬取次数判断是否需要继续爬取,与爬虫自省稍微有所不同,但是原理是一样的)
  • 受ip段的限制,拨号本身可能并不能获取更多的有效ip
  • 如果拨号太频繁,可能会导致拨号错误

如果还有更好的办法,欢迎评论告诉我,感谢各位~

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值