V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
JasonLaw
V2EX  ›  程序员

有方法实现 Selenium 单个 WebDriver 多标签/线程爬取吗?

  •  
  •   JasonLaw · 2020-10-10 15:18:53 +08:00 · 2658 次点击
    这是一个创建于 1503 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以下是我找到的一些资料:

    看起来好像没有方法可以实现“单个 WebDriver 多标签 /线程爬取”,但在Selenium multiple tabs at once - Stack Overflow中,venzen 的评论说

    Multiple threads acting on the same driver instance IS possible with zeroMQ - thread's zeroMQ sends a request to the driver process's zeroMQ server which then acts on the window or desired tab. As many threads as you like.

    venzen 所说的东西是什么?我有点不太理解。真的没有方法实现“单个 WebDriver 多标签 /线程爬取”吗?如果有的话,应该怎么做?

    24 条回复    2020-10-16 17:22:13 +08:00
    chaogg
        1
    chaogg  
       2020-10-10 16:50:08 +08:00
    这 tm 是假装多线程,明明一个线程能传递的指令,他偏偏用多线程传递
    JasonLaw
        2
    JasonLaw  
    OP
       2020-10-10 16:54:39 +08:00
    @chaogg #1 也就是没有办法实现?但是一台电脑能够打开的浏览器个数很有限,请问有没有好的方法解决这个问题?
    zarte
        3
    zarte  
       2020-10-10 16:56:13 +08:00
    多标签与多个浏览器有区别??谷歌的标签不是拖出来也是个新的浏览器了。
    chaogg
        4
    chaogg  
       2020-10-10 17:00:31 +08:00
    @JasonLaw 你是想节约内存吗?可以开多个 tab,能节约一点
    chaogg
        5
    chaogg  
       2020-10-10 17:02:37 +08:00
    你还可以用无头模式,
    yaoye555
        6
    yaoye555  
       2020-10-10 17:08:34 +08:00
    多线程就不用想了,开多个 tab 来同步进行? 切换其实也麻烦,selenium 本身就具有局限性,每次任务清理的再完美 也会动不动就内存泄漏爆了,很烦
    JasonLaw
        7
    JasonLaw  
    OP
       2020-10-10 17:08:56 +08:00
    @chaogg #4 就算是使用多个 tab,单个 WebDriver 还是单线程的,无法做到一个线程对应一个 tab 。最后还是要启动多个 WebDriver 实现并发。
    lijialong1313
        8
    lijialong1313  
       2020-10-10 17:10:26 +08:00
    多标签应该是共享 cookies 的作用吧,要么就是爬虫有速度要求,我是没想到多标签有啥用了
    JasonLaw
        9
    JasonLaw  
    OP
       2020-10-10 17:10:45 +08:00
    @yaoye555 #6 请问有什么替代品可以实现“多线程”的?
    XiaoxiaoPu
        10
    XiaoxiaoPu  
       2020-10-10 17:22:30 +08:00
    venzen 的意思是起一个单独的进程来跑 Selenium,同时这个进程对外提供服务,真正的爬虫进程跟这个服务通信。因为用消息队列解偶了,爬虫本身用多线程就不会影响到 Selenium 了。
    neoblackcap
        11
    neoblackcap  
       2020-10-10 17:33:23 +08:00
    @JasonLaw 典型的 X 问题,Y 问法,得到 Z 的答案。
    你想想你为什么需要用多线程?你不就想节省内存,多跑几个实例嘛。就 chromium 那个架构,你就不用想这回事。而且用 pyppeteer 试试吧。
    koala9527
        12
    koala9527  
       2020-10-10 21:38:38 +08:00
    可以用 Selenium docker 。一个容器一个浏览器多线程爬取。
    wzwwzw
        13
    wzwwzw  
       2020-10-10 22:56:21 +08:00
    试试 Splash ?
    JasonLaw
        14
    JasonLaw  
    OP
       2020-10-11 09:37:06 +08:00 via iPhone
    @XiaoxiaoPu 爬虫不就是 Selenium 吗?
    JasonLaw
        15
    JasonLaw  
    OP
       2020-10-11 09:40:40 +08:00 via iPhone
    @neoblackcap 你说的“ 典型的 X 问题,Y 问法,得到 Z 的答案”是什么? X 问题是? Y 问法是? Z 答案是?我的问题很简单,就是可不可以实现单个 WebDriver 多标签 /线程爬取。
    JasonLaw
        16
    JasonLaw  
    OP
       2020-10-11 09:43:38 +08:00 via iPhone
    @koala9527 我现在用的就是 docker selenium,你说的“一个浏览器多线程爬取”是什么?
    koala9527
        17
    koala9527  
       2020-10-11 10:50:44 +08:00
    @JasonLaw 我的意思是本地开多线程,一个线程驱动一个 selenium node 节点容器,理论上可以实现,但是没有人试过。可以参考 http://dockone.io/article/9257
    neoblackcap
        18
    neoblackcap  
       2020-10-11 14:03:12 +08:00
    @JasonLaw webdriver 多标签跟多线程,你想过这样是一个怎么样的情况吗?
    chromium 是多线程架构的,也就是多开一个 tab 也是多起一个进程。所以首先浏览器方面就不能做到多线程。
    其二你想多个 python 调用一个 webdriver 实例,理论上是可以的。具体我没有尝试。
    neoblackcap
        19
    neoblackcap  
       2020-10-11 14:12:32 +08:00
    @JasonLaw 至于我说你问的是 X 问题,Y 问法,得到 Z 的答案就是说你问的问题并不是你真正面对的问题。你得到的答案不一定是对的。你想用多线程的方式提高并发度,同时复用 webdriver 实例达到减少内存的消耗。这个是你提出“多线程”问题的原因吧?
    如果是面对这个问题,用多线程压根就不是什么好办法,离原始问题太远了。所以我才说 X 问题,Y 问法(多线程编程)。
    首先你的并发度限制在浏览器端,因为主要 IO 发生在这里。你 python 的多线程跟单线程没区别。你一个线程能开 20 个 tab,难道你用多线程开 20 个 tab 就快一点?没有嘛,相反资源消耗还高了,还有线程上下文切换。
    JasonLaw
        20
    JasonLaw  
    OP
       2020-10-11 17:50:33 +08:00
    @koala9527 #17 文章挺好的
    JasonLaw
        21
    JasonLaw  
    OP
       2020-10-11 17:52:17 +08:00
    @neoblackcap #18
    @neoblackcap #19

    谢谢你的回复。
    learningman
        22
    learningman  
       2020-10-11 18:24:23 +08:00   ❤️ 1
    X 问题,Y 问法,得到 Z 的答案
    指的是你遇到了一个问题,你想了一个解法,然后你在实现这个解法的时候又遇到了问题,然后你跑来问怎么解决第二个问题。
    事实上,有可能你想的这个解法本身就有问题,即使帮你实现了这个解法,你的第一个问题也还没有解决
    JasonLaw
        23
    JasonLaw  
    OP
       2020-10-11 18:48:54 +08:00
    @learningman #22 你说得很对,我的原始问题应该是“怎么提高并发度?怎么减少内存消耗?”。
    chaogg
        24
    chaogg  
       2020-10-16 17:22:13 +08:00
    @JasonLaw 一个线程可以对应多个 tab 啊,发送指令时切换窗口对象就行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1425 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:20 · PVG 01:20 · LAX 09:20 · JFK 12:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.