问题出现
我尝试使用如下代码爬取知乎的有关内容,出现知乎安全验证界面:
def init_driver():
options = Options()
options.add_argument("--headless")
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=options)
return driver
if __name__ == '__main__':
driver = init_driver()
driver.get("https://www.zhihu.com/question/610796576/answer/3110013198")
尝试的无效方案
添加启动参数
在网上的许多文章中,反复提到了如下三行代码,然而我将他们加入代码后没有什么效果:
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option('excludeSwitches', ['enable-outomation'])
options.add_experimental_option("useAutomationExtension", False)
JavaScript特殊全局变量
有一些文章提到,通过 WebDriver 启动的网页会存在一些特殊的 JS 变量,这些变量可能会被网站的 JS 识别,例如navigator.webdriver
。我尝试在init_webdriver
底部加入如下代码,也没有生效。
driver = webdriver.Chrome(options=options)
script = '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",
{"source": script})
return driver
也有文章提到,类似的特征变量有二十多个,幸好我知难而退放弃了去一个一个找出来的想法(要是)
其余方案
也看到有知乎网友提出与浏览器指纹有关,声称自己修改特征变量的名称后重新编译 WebDriver 成功解决问题,但是我没有尝试这一方案,不然的话一周后也不一定能有这一篇文章的发布
最终成功的方案
偶然想起查资料的过程中,有人提到在默认情况下,headless 模式打开的浏览器会使用一个包含 headless 关键字的特殊 UA,那么知乎是否是通过这一最简单的方式进行的识别呢?为验证这一猜想,我先将 headless 选项禁用,发现脚本可以正常访问知乎。
那么问题的解决就变得十分简单了,只需要自行指定 UA 即可。最终的init_driver
函数:
def init_driver():
options = Options()
options.add_argument("--headless")
options.add_argument('--disable-gpu')
options.add_argument(
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
)
driver = webdriver.Chrome(options=options)
return driver
一些思考
知乎还是我见过的所有网站中反爬策略比较高级的,从未有人能成功解开他的接口数据加密(有点过于绝对,但至少没公开过),2023年4月以后我更是没见过任何可用的 API 问世。然而仅这一次无头浏览器的限制来看,UA 还是一个比较基简单的策略,基本到现在我们可能已经不会关注这一原始的反爬方式了。以后测试的时候还是要做到滴水不漏,不然又要像我一样耽误一大圈兜兜转转,最后用一行如此简单的代码解决……
对,另外已登录的账号不受这一限制,但是不建议大家冒险(小心封号啊