如何抓取到携程的每个酒店的装修时间和客房数量呢?本文以puppeteer来抓取。
官方demo就很容易上手,再加上awesome-puppeteer中的例子,很容易就可以实现自己的目标。
1 | const puppeteer = require('puppeteer'); |
以上功能都可以直接按上一篇在chrome snippet中实现,但是如果需要自动获取detail信息,就需要puppeteer来帮我们操作了。
1 | // 开始获取detail |
node直接写入csv文件
1 | // 将得到的结果写入csv文件 |
携程会自动监测是不是用了selenium、puppeteer这类工具,在测试的过程中发现,使用正常的Chrome浏览器可以直接打开酒店详情页。但是如果使用火狐浏览器或者puppeteer操控Chrome的话,输入酒店详情链接,会直接从详情页跳转到登陆提示页,打开浏览器调试页面,切换到console栏,输入navigator,发现正常的Chrome和puppeteer打开的Chrome中,navigator主要是webdriver、plugins、mimetypes这几个属性不一样,携程就是根据这几个属性来判断是否要跳转到登录页。
修改webdriver
webdriver标记是反爬一定在检测的属性
目前资料都是
1 | ignoreDefaultArgs: ['--enable-automation'] |
或
1 | Object.defineProperty(navigator, 'webdriver', { |
实测这两种方法已经无效,webdriver还在,只是值为undefined,通过 webdriver in navigator 或者 navigator.hasOwnProperty("webdriver")
都是为true
最终解决方案:
1 | await page.evaluateOnNewDocument(() => { |
改完以后,headless: false
的情况下浏览器不会在自动跳转了,但是改成无头浏览器的话,还是会自动跳转,因为还有其他几个属性不一样。
有两个解决方法:
1.参考本博客中的文章【navigator plugins与mimetyps的模拟实现分析】手动修改。
2.集成扩展组件puppeteer-extra-plugin-stealth,它里面已经把所有属性都改了,可以防止被检测。
不过这个项目半年没更新了,如果报错【browser.setMaxListeners is not a function】,处理方法:
找到puppeteer-extra/packages/puppeteer-extra-plugin-stealth/index.js
第155行:browser.setMaxListeners(30)
,注释掉此行即可。