Chrome Driver 破解反爬
背景
过年回家买机票,各个机票网站上的价格都稍有差别,于是就利用 web-crawler 爬一爬
过程中发现,爬取 qunar 的信息时,qunar 识别了 chrome headless,故意返回了错误的数据
这时只能面向 Google 编程了
解决
理论上,selenium+chromedriver 是可以完全模拟真是浏览器的
但是实际上 chromedriver 在启动的时候,会跟普通的浏览器有些不一样的地方
UserAgent 会带上 headless 标识
解决1
2
3
4
5val options = new ChromeOptions()
options.addArguments(
"--headless",
s"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36"
)js 全局对象有值 : window.navigator.webdriver = true
解决: 通过 driver.executeCdpCommand 在页面加载时期做一些初始化逻辑1
2
3
4
5
6
7
8val driver = new ChromeDriver(buildOptions(requestSetting))
val map = new util.HashMap[String, Object]()
map.put("source", """
|Object.defineProperty(navigator, 'webdriver', {
| get: () => false,
|});
|""".stripMargin)
driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", map)获取 XhrRequest Response
解决:- 通过 performanceLog 拿到 requestId
1
val performanceLog = driver.manage().logs().get(LogType.PERFORMANCE)
- 通过
driver.executeCdpCommand("Network.getResponseBody", cdpMap)
来重放 XhrRequest
1
2
3val cdpMap = new util.HashMap[String, Object]()
cdpMap.put("requestId", requestId)
driver.executeCdpCommand("Network.getResponseBody", cdpMap).asScala.toMap
PS.
selenium 版本
"org.seleniumhq.selenium" % "selenium-chrome-driver" % "4.0.0-alpha-3"