Python 爬虫如何爬取动态网页数据?

2020-04-23 13:15:53 +08:00
 ByteCat
之前看到 Node.js 方面的话 Google 出了一个叫 Puppeteer 的无头浏览器框架,似乎爬动态页面比较方便。

Python 方面的话我搜了一下好像基本上使用 Selenium 来爬,不知道效果和性能如何?毕竟 Node.js 原生对 js 支持很好 😄
6785 次点击
所在节点    Python
19 条回复
Cmdhelp
2020-04-23 13:22:55 +08:00
。。。动态网页,先 f12 看他请求数据的接口,有接口走接口
DelayNoMay
2020-04-23 13:32:25 +08:00
动态只能是 Selenium 了,动态嘛,需要加载时间,肯定比静态的慢
lc1450
2020-04-23 13:40:30 +08:00
后台基于 Headless Chrome,python 可以用 pyppeteer 操作,
这种模式下可以单独在服务器上启动 Headless Chrome 作为服务, 性能就和 chrome 差不多,看机器配置
wework
2020-04-23 13:43:40 +08:00
headless 爬虫 性能都不怎么样.... PHP 的采集 querylist.cc 不错
zdnyp
2020-04-23 13:44:18 +08:00
优先找借口、逆向,不行就上 selenium
sjtiande
2020-04-23 14:00:41 +08:00
万能的 selenum
enrolls
2020-04-23 15:15:35 +08:00
splash?
kr380709959
2020-04-23 15:22:40 +08:00
先抓包看接口,如果接口是明文的,最方便了。如果没找到或者是加密混淆了,走逆向破解,如果没有前端基础放弃这条路。转 selenium,这个可以应对很多动态网站,缺点就是性能低。
ClericPy
2020-04-23 15:40:02 +08:00
一般浏览器打开 Devtools 抓包就够了吧...

至于现在很多人推 Selenium 是因为他们看的教程只提到了这个, 实际上多数情况用 Google 原生的 cdp (HTTP+Websocket) 就够了, Puppeteer 有个 Python 版叫 pyppeteer 就是操作 cdp 的, 功能和 selenium 比只局限在 Devtools 层面, 但是有 js 已经足够了, 平时爬虫来说根本用不到 selenium 更底层的 driver 层面接口

当然, 更无脑的用法也可以 --dump-dom, 反正我是习惯 cdp 了, 自己把接口写写套上就能用
mjvcp
2020-04-23 18:08:58 +08:00
反爬强的网站现在会检测 selenium,感觉 Pyppeteer 稳一点。
NeoIm
2020-04-23 18:41:46 +08:00
@kr380709959 同意 8 楼老哥,数据的话优先看如加载出来的,找接口 url 最直接,F12 或者直接看前端代码都可以,碰到过几次都是可以通过 url 拼接直接抓 json 数据的。
selenium+无头浏览器的模拟加载,效率一般只有几十分之一
feiniu
2020-04-23 19:59:43 +08:00
selenium 不太推荐,有太多反爬都针对他
uti6770werty
2020-04-23 20:21:42 +08:00
@ClericPy 粗略地了解了一下 cdp 这种方式,逻辑上有些不明白。。。
是不是要首先有一个 chrome 的服务进程(本端,或者服务器端)运行着,然后通过操作这个进程的接口去“活动”,来析出页面上的内容呢?
感觉上用起来,还要很熟悉了解页面 DOM 或者 JavaScript 的功能,还有就是 chrome 本身的 API,
不知道这样理解对不对。。。。
ClericPy
2020-04-23 20:31:26 +08:00
@uti6770werty #13 cdp 就是官方提供了一套 API 协议, 可以遵循它的方式 (HTTP / Websocket) 通过 debug port 调试通过调试模式启动的 Blink 内核的浏览器 (Chrome chronium 什么的), 调试的权限基本都集中在平时咱们用的 Devtools 里面那些

你这么理解不算偏, 其实就是给用户开放了个接口控制 Devtools, 熟悉 JS 的话更方便一些, 有时候我还朝 tab 里注入 jQuery vue.js 什么的乱七八糟的.

CDP 文档: https://chromedevtools.github.io/devtools-protocol/

看一眼文档就大致知道了, https://github.com/ClericPy/ichrome 之前自己摸索的时候也写成了代码, 可以稍微看一下 Tab 的部分就明白了, 建立 Devtools 的 ws, 对它 send 指令或者 recv 事件或消息. 实际使用时候最操心的反而是并发控制和僵尸进程的问题更多一点...
uti6770werty
2020-04-23 23:22:33 +08:00
@ClericPy 好的,我去看看,E 文不太好,哈哈。。。
如果自建有个代理池(其实也就 7,8 个在不同运营商的 IP 地址而已),使用代理池来爬目标
是不是 cdp 的服务进程也要分布在这些 IP 上部署?
还是只需一个 cdp 服务进程,能让服务进程使用 IP 池进行轮询?
ClericPy
2020-04-24 09:59:36 +08:00
@uti6770werty #15

几个问题简单回答下:

1. 代理池可以考虑使用 pacfile 的方式 "--proxy-pac-url", 但是 pac 模式不支持 Headless, 所以这个不可取; Chrome 本身不是为爬虫准备的, 所以挂代理这方面想动态的话, 我这边用的有两种方案: 一种是在 upstream 网关那层做负载均衡来不断变换动态 IP(比如用稍微专业点的代理工具, 当时用的 cow 忘了带不带这功能了) 使所有请求挂同一个代理, 该代理则负责负载均衡

2. cdp 起一个守护进程就可以了, 也就是在执行 Chrome 的时候带上 "--remote-debugging-port" 参数, 它内部就启动了一个 http/ws 服务方便调试, 挂代理也就是 "--proxy-server" 这个参数负责, 每个代理启动一个进程其实开销不算太大, 注意下同一个 host 只能建立 6 个连接那个点就好了

3. 想只启动一个 chrome 实例, 用 IP 池轮询的话, 目前没有原生的实现, 要么借助 chrome 扩展, 要么像 1 里说的挂一个动态代理. 如果找到更好的方法, 求告知...

至于 E 文不太好... 其实你看不懂的英文很大几率是写英文的那人语法不行, 一般好的文档单词都是言简意赅的...

可以参考下 [深入浅出 CDP (Chrome DevTools Protocol) - Clericpy's Blog]( https://clericpy.github.io/blog/posts/20200114151137/)
chaosgoo
2020-04-24 11:16:07 +08:00
docker+splash
xiaxichen
2020-04-24 13:53:00 +08:00
学 bom dom js
crella
2020-04-24 15:30:37 +08:00
@ClericPy 之前在 github 找 ruby 的 gui 库的时候,看到一个项目,用 ruby 的 socket 控制本地 chrome.exe 显示的网页来达到“绘制界面”的效果。由于那个项目还在 alpha 阶段,chrome 弹出来就闪退了,我就不明白是什么原理。

现在看来可能和这个 cdp 有点关系。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/665304

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX