更多>>关于我们

西安鲲之鹏网络信息技术有限公司从2010年开始专注于Web(网站)数据抓取领域。致力于为广大中国客户提供准确、快捷的数据采集相关服务。我们采用分布式系统架构,日采集网页数千万。我们拥有海量稳定高匿HTTP代理IP地址池,可以有效绕过各种反采集策略。

您只需告诉我们您想抓取的网站是什么,您感兴趣的字段有哪些,你需要的数据是哪种格式,我们将为您做所有的工作,最后把数据(或程序)交付给你。

数据的格式可以是CSV、JSON、XML、ACCESS、SQLITE、MSSQL、MYSQL等等。

更多>>官方微博

西安鲲之鹏
陕西 西安

加关注

  • 【经验分享】本文介绍了一例APP使用了非常规ssl pinning导致Fidder抓包失败,最终通过Frida HOOK成功解决,附源码。 >>> http://www.site-digger.com/html/articles/20191018/751.html ​​​​
    发布时间:2019-10-18 13:23:42
  • 【经验分享】今日拨号服务器上某PPPOE拨号持续失败,经查日志:“pppoe: send (sendPacket): Network is down”,ip link 查看对应的虚拟网卡状态是DOWN,无法设置为UP(sudo ip link set dev v051802057684 up失败)。但同一个账号在另外一个机器上测试正常,怀疑可能是MAC地址的问题(例如冲突了),果断删掉虚拟网卡( sudo sudo ip link del v051802057684),然后重建并指定一个不同的MAC,拨号成功!
    发布时间:2019-09-26 10:52:18
  • 【经验分享】昨天下午办公室断了下电,服务器重启后,adb devices显示10台设备都是“?????? no permissions”,第一次遇到这种情况。重启服务器和移动设备问题依据。后来在askubuntu上看到有人提到试一下sudo adb devices,竟然立马识别了(https://askubuntu.com/questions/908306/adb-no-permissions-on-ubuntu-17-04)。很诡异,之前用普通权限都一直正常着,为什么突然就没有权限了?
    发布时间:2019-09-26 08:45:09
  • 【经验分享】Termux自带的am命令版本太低,竟然不支持force-stop(如图1示),经查得知pm clear命令也可以停止一个APP,而且还会将APP的用户数据清除掉(回到刚安装的状态),试了一下果然有效,运行之后"/data/data/包名"目录下只剩下lib目录了。注意:需要root权限。 >>> https://stackoverflow.com/questions/3117095/stopping-an-android-app-from-console ​​​​
    发布时间:2019-09-19 12:20:13
  • 【经验分享】"adb shell 命令",如何让“命令”以root权限执行?
    例如,某设备已root,但当执行adb shell rm /data/data/com.xxxx/cache时提示Permission denied。

    解决方法:
    adb shell "su -c '[your command goes here]'"
    例如:
    adb shell "su -c 'rm /data/data/com.xxxx/cache'"

    参考文章"Is there a way for me to run Adb shell as root without typing in 'su'?" >>> https://android.stackexchange.com/questions/5884/is-there-a-way-for-me-to-run-adb-shell-as-root-without-typing-in-su
    发布时间:2019-09-18 09:16:52
  • 【经验分享】关于小红书搜索结果数据抓取的限制:
    1. 小红书微信小程序版之前是前600条可见,最近已被限制为前60条可见。
    2. 小红书安卓APP版本限制为搜索结果前1000条可见。 ​​​​
    发布时间:2019-09-02 16:42:37
  • 【经验分享】通过ADB启动手机淘宝APP搜索,打开指定关键词的搜索结果列表,如下示例,打开搜索“HUAWEI”的结果:
    adb shell am start -n com.taobao.taobao/com.taobao.search.SearchListActivity -d "taobao://s.taobao.com/search?q=HUAWEI" ​​​​
    发布时间:2019-08-22 16:07:00
  • 【经验分享】手机淘宝APP商品搜索结果采集最新方案20190821(免登录)
    (1)模拟操作APP操作,无需登录,不存在封账号;
    (2)IP限制弱;
    详见下附演示视频。  L西安鲲之鹏的微博视频 ​​​​
    发布时间:2019-08-21 17:52:28
  • 【经验分享】终于搞定了支付宝口碑App数据采集,有图有真相。 ​​​​
    发布时间:2019-08-09 17:52:21
  • 【经验分享】如何采集支付宝小程序的数据?adb模拟操作 + xposed Hook "com.alipay.mobile.nebula.util.H5Utils.parseObject"
    如附图所示,成功获取服务端应答的JSON数据。 ​​​​
    发布时间:2019-08-07 16:13:23
当前位置: 首页 > 技术文章 >
远程GeckoDriver的使用
发布时间:2019-03-13

什么是GeckoDriver?

如果你用过Selenium + Firefox,那你应该对geckodriver.exe(Linux下是geckodriver)不陌生。 如下图所示, GeckoDriver起着一个“Selenium测试脚本”与“火狐浏览器”沟通的中间桥梁作用:

  • GeckoDriver提供了一个HTTP API接口,使用W3C WebDriver协议。
  • Selenium通过W3C WebDriver协议和GeckoDriver进行交互(提交命令,获取结果)。
  • GeckoDriver使用Firefox Remote协议与Firefox浏览器进行交互,转发Selenium的命令和火狐浏览器的应答。

更形象的解释:

  1. 1. "Selenium"是一个只会说“W3C WebDriver协议”话的人;
  2. 2. “火狐浏览器”是一个只会说“Firefox Remote协议”话的人;
  3. 3. "GeckoDriver"是一个翻译,它通晓“W3C WebDriver协议”和“Firefox Remote协议”两门语言;
  4. 4. 在GeckoDriver的帮助下,Selenium能够和火狐浏览器进行无障碍沟通;

什么是远程GeckoDriver?

默认GeckoDriver监听127.0.0.1:4444(如下图所示),因此只能够本地连接。

可用通过--host和--port参数来指定监听的IP和端口。比如监听0.0.0.0:56600:

geckodriver --host 0.0.0.0 --port 56600

这样我们就能远程访问这个GeckoDriver接口,进而能够在远程主机调用GeckoDriver所在机器上的Firefox浏览器。如下图所示:

为什么需要远程GeckoDriver?

    设想一下,我们拥有一个20台服务器组成的爬虫集群,每个服务器上启动20个浏览器实例,总共就有400个浏览器。我们该如何有效地控制这400个浏览器呢?

    按照传统的方式我们需要在每台服务器上部署Selenium脚本,通过本地GeckoDriver调用各自的20个浏览器,这似乎也没什么问题。但是,如果我们修改了爬虫脚本或者需要更换代理列表,就要在20台机器上重新部署一遍,首先要更新相关文件,然后要杀掉之前的爬虫进程,再启动新的进程,20台机器挨个操作一遍非常繁琐(而且很容易遗漏)。

    使用远程GeckoDriver就可以避免这个问题,我们只需要在一台机器上部署Selenium相关脚本,然后通过远程调用这400个浏览器即可。后续修改代码也仅需要在这一台机器上做变更。

如何使用远程GeckoDriver?

Selenium.webdriver.Firefox默认启动并使用本地GeckoDriver,不支持远程GeckoDriver。需要我们稍作修改,代码如下所示:

# coding: utf-8
# test.py

from selenium import webdriver
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class FirefoxRemoteWebDriver(webdriver.Firefox):
    """调用火狐远程geckodrivery服务
    """
    def __init__(self, remote_url, firefox_profile=None, timeout=30, capabilities=None, options=None, firefox_options=None):
        self.remote_url = remote_url
        if firefox_options:
            options = firefox_options
        self.binary = None
        self.profile = None
        class Service:
            def __init__(self):
                pass
            def stop(self):
                pass
        self.service = Service()
        if capabilities is None:
            capabilities = DesiredCapabilities.FIREFOX.copy()
        if options is None:
            options = webdriver.firefox.options.Options()
        if firefox_profile is not None:
            options.profile = firefox_profile        
        capabilities = dict(capabilities)
        capabilities.update(options.to_capabilities())
        executor = webdriver.firefox.remote_connection.FirefoxRemoteConnection(remote_server_addr=self.remote_url)
        RemoteWebDriver.__init__(
                        self,
                        command_executor=executor,
                        desired_capabilities=capabilities,
                        keep_alive=True)     
        self._is_remote = False
        
if __name__ == '__main__':
    # test
    options = webdriver.firefox.options.Options()
    # Headless模式 - 不显示浏览器UI
    options.set_headless(True)
    # 使用远程GeckoDriver, 接口地址:http://123.138.107.217:56600
    firefox = FirefoxRemoteWebDriver(remote_url='http://123.138.107.217:56600', options=options)
    firefox.get('http://httpbin.org/ip')
    firefox.save_screenshot('test.png')
    print firefox.page_source

如下图所示是上述测试代码运行保存下来的屏幕截图文件test.png:

结合我们在项目中遇到的各种问题,我们对Selenium.webdriver.Firefox进行了重新封装,更加便于在爬虫项目中使用。

代码(firefox.py)在这里:https://bitbucket.org/qi/ghostkzp/src/ef4134889a4d89d613b89fa5aafe2c66dce7809f/firefox.py?at=default&fileviewer=file-view-default

主要有如下特点:

  • 支持代理HTTP Proxy Basic Authentication,支持两种实现方式;
  • 可以禁用图片加载;
  • 可以隐藏浏览器UI(headless模式);
  • 设置浏览器UA;
  • 支持远程GeckoDriver调用;
  • 支持导出/导入Cookie文件;

GeckoDriver管理器

为了便于管理GeckoDriver进程,我们编写了一个管理脚本,它通过Web API接口提供如下功能:

(1) /ports/

返回所有GeckoDriver监听端口,JSON格式。

(2) /restart/

重启指定的GeckoDriver进程(根据端口对应),并关闭对应的Firefox进程。用以解决远程连接GeckoDriver出现Session is already started问题。

GeckoDrive管理器(geckodriver_service.py)的代码:https://bitbucket.org/qi/ghostkzp/src/ef4134889a4d89d613b89fa5aafe2c66dce7809f/service/geckodriver_service.py?at=default&fileviewer=file-view-default

用法:

python geckodriver_service.py
程序运行后默认启动10个GeckoDriver进程,依次监听56600 ~ 56609 端口。并在5363端口提供Web API服务。
我们只需要将其添加到每个爬虫服务器自启动服务中即可。为了安全起见,需要使用iptables配置相应的IP白名单,只允许授权的IP访问。

查看可用GeckoDriver端口:

访问http://主机IP:5363/ports/, 返回如下图所示:

重启指定的GeckoDriver进程:

例如 重启56600端口对应的GeckoDriver。访问 http://主机IP:5363/restart/56600/。
PS:上述的"主机IP"指的是运行geckodriver_service.py的机器IP。

参考文章:

https://github.com/mozilla/geckodriver

https://w3c.github.io/webdriver/#protocol

https://firefox-source-docs.mozilla.org/testing/marionette/Protocol.html

特别说明:该文章为鲲鹏数据原创文章 ,您除了可以发表评论外,还可以转载到别的网站,但是请保留源地址,谢谢!! 本文旨在技术交流,请勿将涉及的技术用于非法用途,否则一切后果自负。
☹ Disqus被Qiang了,之前所有的评论内容都看不到了。如果您有爬虫相关技术方面的问题,欢迎发到我们的问答平台:http://spider.site-digger.com/
QQ在线客服
欢迎咨询,点击这里给我发送消息。
欢迎咨询,点击这里给我发送消息。

加微信咨询