python requests 反机器人检测?
我一直在用 requests
这个库来抓取一个网站的数据。在10分钟内,我对这个网站的请求次数不多,大概是25次左右。可是突然间,网站就给我返回了一个404错误。
我想问的是:我看到过一些地方说,用浏览器访问一个网址和用像 requests
这样的工具访问是有区别的。因为 requests
获取数据时不会像浏览器那样获取 cookies 和其他信息。那么在 requests
中有没有什么选项可以模拟浏览器的行为,这样服务器就不会认为我是在用机器人访问?还是说这个根本就不是问题?
3 个回答
第一个回答有点偏差,Selenium 还是可以被检测到,因为它是一个网页驱动程序,而不是普通的浏览器。它有一些固定的值,这些值可以通过 JavaScript 被发现。大多数网站使用指纹识别库来找到这些值。幸运的是,有一个修补过的 Chrome 驱动程序,叫做 undetecatble_chromedriver,可以绕过这些检测。
一些通用的帮助建议:
- 请求头应该和常见浏览器相似,包括:
- User-Agent:使用一个比较新的版本(可以查看 https://developers.whatismybrowser.com/useragents/explore/),或者更好的是,如果你要发多个请求,可以随机选择一个新的版本(可以参考 https://github.com/skratchdot/random-useragent)
- Accept-Language:类似于 "en,en-US;q=0,5"(根据你的语言进行调整)
- Accept:一个标准的格式可以是 "text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8"
- 导航:
- 如果你要发多个请求,建议在它们之间设置一个随机的时间间隔
- 如果你打开页面中的链接,要相应地设置Referer头
- 或者更好的是,模拟鼠标活动来移动、点击和跟随链接
- 图片应该是启用的
- Javascript也应该是启用的
- 检查"navigator.plugins"和"navigator.language"在客户端的Javascript页面上下文中是否被设置
- 使用代理
基本上,你可以做的至少一件事就是发送 User-Agent
这个头信息:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0'}
response = requests.get(url, headers=headers)
除了使用 requests
,你还可以通过 selenium 来模拟一个真实用户——它使用的是一个真实的浏览器——在这种情况下,很明显没有简单的方法可以区分你的自动化用户和其他用户。Selenium 还可以使用一种“无头”浏览器。
另外,检查一下你要抓取的网站是否提供 API。如果没有 API 或者你没有使用它,确保你知道这个网站是否允许像这样进行自动化抓取,看看他们的 使用条款
。你知道,网站可能会在一段时间内请求过多后阻止你,这肯定是有原因的。
还可以查看:
编辑1:selenium 使用的是一个 webdriver,而不是一个真实的浏览器;也就是说,它在头信息中传递了 webdriver = TRUE
,这使得它比 requests
更容易被检测到。