以下转自:fengzifz 2021年6月17日
Python + selenium 如何绕过爬虫特征检测?
在信息时代,数据变得越来越重要。然而并不是每一家公司都是腾讯、百度、知乎、字节跳动等,在日常业务中就可以产生大量的内容或用户数据。很多人在互联网获取数据时,都是使用爬虫获取,而爬虫也是一种最经济实惠的获取数据手段。
但爬虫需要遵守 robot 协议,并且在不损害目标服务器的情况下进行。然而,很多爬虫却不理会 robot 协议,并且不对爬取频率进行限制,高并发的爬虫严重占用了服务器的资源,并会影响真正用户的体验。所以,现在很多公司都专门的反爬团队,爬与反爬之间,不断博弈,技术不断升级,从某种意义上,这也是促进了行业的进步。
很多爬虫新手常常抱怨自己写的爬虫 demo 获取的内容和自己手动打开浏览器的不一样。这种往往是连 user agent 没有设置、请求频率都没有控制,第一时间就被检测到时非用户访问,不把你放进蜜罐才怪呢。
爬虫技术,是一种非常综合的技术。不是你学会 request,学会用 bs 解析 html 并保存内容就学会了,你只会这些,也就只能爬取一些小站或者 demo 页面。爬虫的难点往往在于如何绕过爬虫识别,即反反爬虫。
如果你需要爬取如知乎、淘宝,往往需要借助 selenium 工具。我在 2011 年的时候就接触过 selenium,那时用 selenium + cucumber + ruby 来做自动化测试,那时的 selenium 也没有现在那么完善。
那么该如何绕过爬虫识别呢?
selenium webdriver 有哪些爬虫特征,我不复制黏贴了,网上很多文章都有了。而为了方便,可以直接打开这个页面去检测:Antibot。
如下图所示,左边是正常打开的页面,右边是用 selenium webdriver 打开的页面。红线框里面的内容就是爬虫特征。当然,如果你使用 headless 模式,会有更加多的爬虫特征被检测出来。
以下一步步消除这些特征。
1. “Chrome 正受到自动测试软件的控制。”
selenium 提供了接口去消除这个,你只需要在你的代码里面加入:
options.add_experimental_option('excludeSwitches', ['enable-automation'])
2. WebDriver (New) present (Failed)
这个可以通过禁用 blink 特征。Blink 是 Chromium 的渲染引擎,V8 也是基于 Blink 开发的 JavaScript 引擎,具体原理我没有搞明白,猜测是 selenium 使用了一些 Blink 的特征,而原来 Chrome 是没有的。
options.add_argument('--disable-blink-features=AutomationControlled')
3. “webDriver”: true, “webDriverValue”: true
关于这点,可以看上图左右两边,不管我是手动打开,还是用脚本打开,webdriver 都已经被标记为 true。我猜测是因为我曾经使用 selenium 打开这个爬虫特征检测网站,它已经记录了我的浏览器指纹,所以现在不管我是用 selenium 打开还是手动打开,都已经被标记为 true。所以,如果你曾经用脚本打开过某些网站,那么你很大概率都已经被对方记录了浏览器指纹,从而把你标记为疑似爬虫访问,而不敢你是不是真实访问。
那么思路就是隐藏浏览器指纹了。
Python 的 pyppeteer 可以用来隐藏浏览器指纹,但这个类库从 2018 年就已经没更新了,但谷歌团队维护的 puppeteer/puppeteer 却一直在更新。因此,国外有个叫 berstend 的开发者,写了一个 puppeteer-extra 插件来提取隐藏浏览器指纹特征的 js 脚本 stealth.min.js
,那么我们用 selenium 打开页面之前,运行这个脚本,就可以成功隐藏浏览器指纹了。
如果你的环境已经安装了 nodejs,那么直接运行下面命令,就会在你当前的目录生成 stealth.min.js 文件了。
npx extract-stealth-evasions
想了解具体过程的朋友,可以查看:berstend/puppeteer-extra。
最后,在 python 里面,加入下面代码:
with open('./js/stealth.min.js') as f:
js = f.read()
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": js
})
运行后,浏览器指纹特征也被隐藏了。
参考资料: