怎么爬取动态生成的网页?
发布于 9 个月前 作者 JZLeung 3382 次浏览 来自 问答

比如京东的商品列表页,列表中的价格和评论都是通过jsonp获取,再渲染出来的。而用 nodecrawler 只能爬取最原始的页面,请问如何才能等页面的js执行完毕后才返回html? 先谢谢各位大佬的提议。

32 回复

phantomjs模拟请求,不过速度很慢.如果对速度有要求的话比如可以对京东抓包,找出接口,然后再用正则匹配来截取jsonp里想要的数据

@oyosc 有接口,但是有很多个,一页所有商品需要访问3个接口各3次。 自豪地采用 CNodeJS ionic

@JZLeung 这就要看你想要的数据是啥了,原理都一样

这不是更好吗?页面都不用爬了,直接调取它接口

@zy445566 可是不爬没有sku 的ID。 自豪地采用 CNodeJS ionic

selenium phantomjs nightmare 都可以

一般来说,常见的就是容器和找接口。 不过如果对稳定性没有太高的要求,其实还有一个方案,直接控制台或者暴力猴,通过jquery 和 cors 把数据提交给服务器。

既然有接口,直接调接口拿数据就好了呀

这个问题无数的人已经总结无数次。请百度

用scrapy+selenium,很轻松

用谷歌network 可以看到接口url,直接爬接口 然后整理数据就行

puppeteer 不解释

puppeteer: 我不管你是不是动态页面,只要你是web,撸起袖子就是干

我的天,这么简单

@178220709 这个肯定不行的。。。。因为要实时爬取。

@wd4219 如果京东的接口有这么简单就可以破的话,我就不用来发帖啦。

@ianchn 百度的结果,基本都是要不Python(可是我不会),要不就是phantomjs(太慢了,因为有几十个页面,每个页面又有几十个请求)

@Kevinzhang29 有jsonp的url但是还是需要先爬取需要的sku的id。

@atian25 @JasonBoy 这个 puppeteer 的速度如何?能不能在几分钟内爬完100个页面?

@pengliheng 能说下思路吗?谢谢。

@JZLeung 我爬携程酒店就是这样的,虽然麻烦 但是你爬了id什么的之后 建立自己的数据库 接下来只要爬就行了。

方向1 headless类

  • 工具:puppeteer(推荐), phantomjs(基本已经不会再更新)
  • 场景:如果对抓取不熟悉,或者页面js做了太多事情,接口响应和你最终要的东西相差很多时。
  • 优点:省心,前端开发熟悉的套路。headless类的帮你模拟出浏览器的加载过程,你自己拿渲染生成好的数据就可以了。
  • 缺点:可定制化低-> 易被防抓; 性能差

方向2 抓接口

  • 工具:你熟悉语言的httpRequest库
  • 场景:熟悉抓取,你能分析出你要的数据来自那些接口以及接口的前后逻辑;性能要求高
  • 优点:可定制化高,请求你想发成啥样都可以;性能好
  • 缺点:对开发者分析能力和动手能力要求高

至于性能相差多少,可以理解成进程级别和请求级别,这要看具体抓取目标环境和你的具体实现了。

如果楼主还是一脸懵的话,建议你甭管用啥,先run起来,渐渐就有感觉了

@Kevinzhang29 那你是先爬完所有的id再去更新各个id的数据还是爬一些更新一些这样呢?

@soda-wy 好的,感谢这么详细的解答。我试试两种的效率。

@JZLeung 把所有静态的数据拿到之后

@JZLeung puppeteer 只是一个 headless 的 chromium 浏览器而已,Google 官方出来的,所以之前的 phantomjs,casperjs,nightmare 就结束了历史使命了。

抓取速度只看你网速,反正一般爬虫你都是搞集群的,所以 puppeteer 的启动速度可以忽略不计(比起其他几个,它的启动速度已经是最快的了)。

还是要看你的具体业务场景,简单的那种还是直接 curl 快,需要执行 js 的,非 puppeteer 莫属。

https://github.com/GoogleChrome/puppeteer

@atian25 我只是个业余的,集群什么的都不懂。现在正在研究puppeteer 但是扔上服务器后(阿里的装不上chromium,扔的国外)动不动就30s超时。醉了。

@JZLeung 说明你的服务器跟你要抓取的网站之间的访问速度太慢了…

@atian25 好吧,确实是这样的。用阿里云就基本维持在1s左右一个页面。

我是这样安装chromium的 ,设置一个 。。。skip。。。= true 的参数来跳过chromium安装,然后手动安装chromium

const browser = await puppeteer.launch({
    executablePath : 'C://Users/33318/AppData/Local/Chromium/Application/chrome.exe',
});

指定chromium的绝对地址

@pengliheng 好的,我也是这么做的。然后在我国外的服务器,只需2s就下载好了。。。。万恶的高墙。 自豪地采用 CNodeJS ionic

回到顶部