Open chenxiaochun opened 7 years ago
感谢,提供了思路
客气,互相交流哈。
感谢
友情提示一下,这种情况被无限加载的页面(例如微博feed流之类的)坑到,建议参考这个方案:
https://www.screenshotbin.com/blog/handling-lazy-loaded-webpages-puppeteer
@felix021 ,我的方案在最初确实没有考虑无限加载的情况。其实对于无限加载的页面,可以设置一个最大截取长度。
mark 等下来看
This was helpful, thanks.
最近在开发一个网页链接抓取工具,需要将页面中所有的链接都抓取下来进行分析。
对于一般网页来说很好处理,直接去抓取页面的源代码,然后将其中的链接分析出来即可。但是京东商城的大部分页面都使用了懒加载的机制,只有用鼠标真正滚动页面之后,才会加载楼层数据。
所以,我得用 js 实现一个自动滚动页面的功能,当页面滚动结束之后,再去触发抓取链接机制。这里面有一个难点是怎么才能感知到页面已经滚动到最底部了,可以进行后续操作了。因为 js 中并没有什么原生方法能告诉你滚动条的滚动状态,所以我想到可以使用
async + await + setInterval
来模拟一下这个操作。先来看一个简单的示例,我定义了一个
sleep
函数,参数ms
的默认值为 3000 毫秒。运行代码,立刻输出的是 1,后面的 2 并没有立刻输出,而是等待 3 秒之后才会看到。它的实现原理就是,
sleep
函数返回的是一个Promise
对象,在async
函数中调用sleep
函数时添加了await
关键字。代码执行到此处就会暂停,然后等待sleep
函数状态变为resolve()
之后,才会继续执行。有了上面的功能做基础,接下来就是如何实现页面滚动的功能。
定义变量
totalHeight
用来存储已经滚动的总高度,distance
用来存储每次滚动的高度。页面每滚动一次,totalHeight
就累加一次,然后将它与页面的scrollHeight
进行比较,直到大于等于它为止。这时候说明页面确实已经滚动到了最底部。抓取页面链接我用的是 GoogleChrome 团队出品的 Puppeteer 。
所谓无头浏览器,可以理解为没有界面的浏览器。也就是说,可以使用这个库在不需要打开浏览器界面的情况下去模拟用户的行为操作。
puppeteer.launch()
方法创建一个浏览器实例,传入headless: false
参数是为了打开浏览器的操作界面,这样我们才能看到后面模拟的滚动操作。browser.newPage()
方法是创建一个标签页,并设置它的可视区域大小为 1200*800。page.goto()
方法就是在当前创建的标签页中打开我们指定的链接。现在把滚动页面和抓取页面链接的功能添加进来。
上面的
scrollTimer
就是用来滚动页面,返回的是一个Promise
对象。下面的crawler
在等待页面滚动完毕之后,就开始抓取页面中所有的链接[...document.querySelectorAll('a')]
,分析完之后将数据返回。无意中看到另外一种页面滚动的实现方式:https://github.com/GoogleChrome/puppeteer/issues/844