编写一个爬虫的思路,当遇到反爬时如何处理

本文介绍了编写爬虫时遇到反爬机制的处理方法,包括加代理、降速、破解接口和多注册账户。强调了爬虫任务的特点是IP密集型,建议使用简单工具和避免高并发。还分享了拿到抓取任务时的思路,如针对数据量小的抓取、动态加载页面、IP封禁和账户或验证码的处理。最后指出,加IP池是最直接有效的解决方案。
摘要由CSDN通过智能技术生成

写了这么多年爬虫了,经常还是会撞上反爬机制。虽然大多数时候都能解决,但是毕竟反爬机制多种多样,有时候遇到一个许久不见的反爬机制,也会感到手生,一时想不上来应对方法,而浪费不少时间。最近写了不少爬虫,接下来一段时间又不写了,趁着手还比较熟,记录一下备忘,方便大家也方便自己。

之前写过一篇常用的反爬虫封禁手段概览, 但是主要是从反爬的角度来的,这篇主要从写爬虫的角度来说说。

开章明义,当遇到反爬机制时,想要做到把数据爬下来,无非四个方法:

  1. 加代理
  2. 降速度
  3. 破解接口
  4. 多注册几个账户

好多文章为了显示自己高大上,吹些什么高并发呀,分布式,机器学习破解验证码的幺蛾子,都是扯淡。与其扯这些东西,不如老老实实把数据爬下来才是王道,如果非要扯上一些 fancy 的东西,那把监控做好比啥都重要

补充说明一下,本文探讨的是数据收集型的小型爬虫,也就是你要对少数站点在较短时间内收集大量信息。而非搜索引擎型全网爬虫,即对大量站点在较长时间内收集综合信息。(全网当然要上高并发了)

为什么说爬虫不要扯高并发?

我们知道计算机程序按瓶颈不同大概分为两类,CPU 密集型和 IO 密集型。CPU 密集型就是偏重计算的任务,比如说编解码啥的;IO 密集型就是偏重于网络的任务,比如说下载或者 web 服务器。那么爬虫是哪种呢?你估计要回答 IO 密集型,恭喜你答对了。但是这不是我想说的重点,重点是爬虫不光是 IO 密集型的任务,实际上我想把它称作 IP 密集型任务。

什么是 IP 密集型任务呢?按照上面的定义我们知道,也就是说,对爬虫来说,**最瓶颈的地方其实是你持有的 IP 的数量!**作为一个合格的爬虫编写者,你肯定已经擅长伪造各种 HTTP headers, 破解 JS 的加密参数,但是唯独一个 -- 来源 IP -- 你是无法伪造的。好多看起来很难搞的事情,如果对方站点的小霸王服务器撑得住,只要加上足够的 IP 就很简单啦,不用绞尽脑汁去想各种策略了。

为什么不要用现成的框架?

上面说了,所谓的"高并发"对爬虫没有任何卵用,那么像是 Scrapy 这种采用了协程以便提高并发的框架我就不是很懂了。以前我专门写过一篇为什么不要用 Scrapy 的文章,所以这里就不再展开细说了。

另外如果你爬虫写多了肯定有自己的一套东西了,这时候你可能会有自己的一个小框架,这是可以的。但是我还是想提两点:

  1. 千万不要做成从模板生成新的爬虫项目的功能。假如你改了模板里的一个 bug 怎么办?以前生成的爬虫还挨个修改吗?
  2. 框架尽量简单,把可以复用的功能提取成单独的 utility 函数或者库。难免有需要改框架或者不适用框架的时候,这时候依然可以复用单独的模块。
编写一个反爬程序是针对那些想要保护其网站内容不被自动化程序抓取的网站管理员来说的。反爬程序的目的是防止或限制爬虫访问网站资源。下面是一个简单的例子,展示如何在Python编写一个基本的反爬虫程序: 1. **检查用户代理(User-Agent)**: 爬虫通常会有一个特殊的User-Agent字符串,可以通过检查请求的User-Agent来识别爬虫。 ```python from flask import Flask, request, make_response app = Flask(__name__) @app.before_request def check_user_agent(): user_agent = request.headers.get('User-Agent') blocked_user_agents = ['Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'] if user_agent in blocked_user_agents: return make_response('Forbidden', 403) if __name__ == '__main__': app.run() ``` 2. **使用robots.txt**: 通过遵循robots.txt文件中的规则,爬虫可以知道哪些页面它可以访问,哪些不可以。 ```python import urllib.robotparser rp = urllib.robotparser.RobotFileParser() rp.set_url("http://www.example.com/robots.txt") rp.read() def can_fetch(url): return rp.can_fetch("*", url) # 在请求之前检查是否可以抓取 if not can_fetch('http://www.example.com/some-page'): # 如果不能抓取,则退出或者进行其他处理 ``` 3. **检测IP地址**: 如果发现某个IP地址频繁请求,可以暂或永久地阻止该IP地址。 ```python from flask import Flask, request, make_response from collections import deque app = Flask(__name__) ip_queue = deque(maxlen=10) @app.before_request def check_ip_frequency(): ip = request.remote_addr ip_queue.append(ip) if len(ip_queue) == 10 and ip_queue.count(ip) > 5: return make_response('Too many requests from your IP', 429) if __name__ == '__main__': app.run() ``` 4. **动态令牌或验证码**: 对于需要登录的页面或者高频率请求,可以使用验证码或者动态令牌来增加自动化访问的难度。 5. **模拟正常用户行为**: 设置合理的请求间隔,不直接使用爬虫程序的IP地址等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值