0%

window.scrollTo失效了怎么办?使用puppeteer实现屏幕滑动效果


又是很久没有写博客了,最近在搞漫画爬虫项目时发现某些网站把window.scrollTo方法都屏蔽了,由于大多数漫画网站都是在网页滚动时动态加载,所以如果无法实现网页滚动是没办法爬取到所有漫画的,幸好还好有google爸爸维护的puppeteer爬虫框架,这个强大的框架当然是无视这些方法屏蔽的,它可以实现鼠标按下,滑动,弹起等一系列自动化操作,那么利用这些方法我们就可以实现网页滑动了,在此,针对原生滑动方法都被屏蔽的情况下,利用puppeteer实现网页滑动做一个记录。如果有更好的方法的小伙伴欢迎一起交流讨论。


前几天我维护代码的时候,突然发现爬虫代码报错了😂

打开该网站的控制台调试,输入window.scrollTo(0, 800);

控制台输出结果为:Uncaught TypeError: window.scrollTo is not a function

然后再打印一下window这个实例:console.log(window)

可以看到scrollTo: null

估计是网站为了反爬取而采用的措施,直接把window.scrollTo等原生方法赋值为空。

初始化

获取浏览器页面实例

1
2
let browser = await puppeteer.launch({ headless: true })
let page =await browser.newPage()

模拟PC的尺寸和UA

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 模拟pc设备mac
*/
exports.viewPort = {
width: 1080,
height: 1920
}
const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
/**
* 设置屏幕尺寸和UA
*/
await page.setViewport(viewPort);
await page.setUserAgent(userAgent);

实现网页滑动

利用鼠标动作组合

1
2
3
4
5
6
7
8
9
10
exports.scrollPage = async function (distance) {
await page.mouse.move(Spider.viewPort.width/2, Spider.viewPort.height * 0.9, {steps: 10})
await page.mouse.down(Spider.viewPort.width/2, Spider.viewPort.height * 0.9)
if (Spider.viewPort.height * 0.9 - distance > Spider.viewPort.height * 0.05){
await page.mouse.move(Spider.viewPort.width/2, Spider.viewPort.height * 0.9 - distance, {steps: 10})
}else{
await page.mouse.move(Spider.viewPort.width/2, Spider.viewPort.height * 0.05, {steps: 10})
}
await page.mouse.up()
}

distance是y轴滑动的垂直距离,根据屏幕尺寸计算出鼠标滑动到的组合操作的起始位置x和y的坐标点,然后模拟鼠标按下操作。因为我们需要爬取的网页,屏幕高度的5%是顶部固定的导航栏,所以结束位置的y轴坐标应该大于屏幕高度的5%。由于我们的网页滑动操作普遍是鼠标由下往上滑动,所以我们需要判断一下动作当前的起始位置的y轴坐标减去滑动的垂直距离后的y轴坐标值是否大于屏幕高度的5%,如果是,结束位置的y轴坐标为鼠标按下操作的y轴坐标减去滑动的垂直距离,否则结束位置的y轴坐标即为屏幕高度的5%。将window.scrollTo方法替换为我们自定义的scrollPage方法,传入滑动的垂直距离即可。