V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ByteCat
V2EX  ›  Python

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

  •  
  •   ByteCat · 2020-04-23 13:15:53 +08:00 · 6733 次点击
    这是一个创建于 1678 天前的主题,其中的信息可能已经有所发展或是发生改变。
    之前看到 Node.js 方面的话 Google 出了一个叫 Puppeteer 的无头浏览器框架,似乎爬动态页面比较方便。

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

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

    当然, 更无脑的用法也可以 --dump-dom, 反正我是习惯 cdp 了, 自己把接口写写套上就能用
    mjvcp
        10
    mjvcp  
       2020-04-23 18:08:58 +08:00
    反爬强的网站现在会检测 selenium,感觉 Pyppeteer 稳一点。
    NeoIm
        11
    NeoIm  
       2020-04-23 18:41:46 +08:00
    @kr380709959 同意 8 楼老哥,数据的话优先看如加载出来的,找接口 url 最直接,F12 或者直接看前端代码都可以,碰到过几次都是可以通过 url 拼接直接抓 json 数据的。
    selenium+无头浏览器的模拟加载,效率一般只有几十分之一
    feiniu
        12
    feiniu  
       2020-04-23 19:59:43 +08:00 via iPhone
    selenium 不太推荐,有太多反爬都针对他
    uti6770werty
        13
    uti6770werty  
       2020-04-23 20:21:42 +08:00
    @ClericPy 粗略地了解了一下 cdp 这种方式,逻辑上有些不明白。。。
    是不是要首先有一个 chrome 的服务进程(本端,或者服务器端)运行着,然后通过操作这个进程的接口去“活动”,来析出页面上的内容呢?
    感觉上用起来,还要很熟悉了解页面 DOM 或者 JavaScript 的功能,还有就是 chrome 本身的 API,
    不知道这样理解对不对。。。。
    ClericPy
        14
    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
        15
    uti6770werty  
       2020-04-23 23:22:33 +08:00
    @ClericPy 好的,我去看看,E 文不太好,哈哈。。。
    如果自建有个代理池(其实也就 7,8 个在不同运营商的 IP 地址而已),使用代理池来爬目标
    是不是 cdp 的服务进程也要分布在这些 IP 上部署?
    还是只需一个 cdp 服务进程,能让服务进程使用 IP 池进行轮询?
    ClericPy
        16
    ClericPy  
       2020-04-24 09:59:36 +08:00   ❤️ 1
    @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
        17
    chaosgoo  
       2020-04-24 11:16:07 +08:00
    docker+splash
    xiaxichen
        18
    xiaxichen  
       2020-04-24 13:53:00 +08:00
    学 bom dom js
    crella
        19
    crella  
       2020-04-24 15:30:37 +08:00 via Android
    @ClericPy 之前在 github 找 ruby 的 gui 库的时候,看到一个项目,用 ruby 的 socket 控制本地 chrome.exe 显示的网页来达到“绘制界面”的效果。由于那个项目还在 alpha 阶段,chrome 弹出来就闪退了,我就不明白是什么原理。

    现在看来可能和这个 cdp 有点关系。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4829 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 03:59 · PVG 11:59 · LAX 19:59 · JFK 22:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.