更多>>关于我们

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

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

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

更多>>官方微博

西安鲲之鹏
陕西 西安

加关注

  • 【经验分享】Linux server(headless模式)下Android模拟器的实现。

    现在越来越多的采集项目(采集APP数据)需要用到安卓模拟器了,然而市面上还没有支持Linux server(headless模式)下运行的安装模拟器,太遗憾了(因为公司大多数服务器都是Ubuntu server版本)。

    我们可以使用KVM + Android x86版系统来实现:

    1. 安装配置KVM。关于KVM在Ubuntu server下的安装配置步骤,详见我们去年的这篇文章:http://t.cn/EGdGjVE
    2. Android x86是支持运行于 x86 PC上的Android操作系统。下载Android X86 系统安装ISO文件,下载地址:https://osdn.net/projects/android-x86/releases,我测试的是android-x86-6.0-r3.iso。
    3. 创建KVM虚拟硬盘:
    qemu-img create -f qcow2 ./android60-1/android.img 10G
    PS:磁盘大小10GB,虚拟磁盘文件存储路径./android60-1/android.img(后面要用到)。
    4. 创建好网桥br0(直连主机外网,如附图1所示)。让虚拟机通过桥接模式上网,这样我们就可以很方便的从外网使用adb连接5555端口,进行远程控制。网桥的配置方法详见http://t.cn/EGdGjVE
    5. 启动KVM虚拟机,安装Android x86系统:
    qemu-system-x86_64 -enable-kvm -m 2048 -smp 4 -cdrom "android-x86-6.0-r3.iso"  -hda "./android60-1/android.img" -net nic,model=virtio,macaddr=00:16:3E:51:CC:10 -net bridge,br=br0  -vnc :2

    PS: 2048M内存,4核CPU,光驱链接系统安装镜像文件android-x86-6.0-r3.iso,指定虚拟机使用00:16:3E:51:CC:10这个MAC,使用网桥br0,指定VNC端口为5900 + 2 = 5902。

    执行上述命令之后,就可以通过VNC连接5902端口,进行系统安装了,安装过程很简单,跟其它Linux发行版安装过程类似:先是分区,格式化磁盘,然后写入文件,重启(如附图2所示)。
    6. 系统好之后,再次运行上述命令(注意要把-cdrom相关参数去掉,否则默认还会从光盘启动),首次进入系统,需要完成系统初始化配置。

    PS:需要注意的是,如果卡到WIFI配置那里了(提示无法连接网络,安装向导无法连接到谷歌,原因你懂的),可以先关掉网络,方法是按Alt + F1,进入安装命令行模式(可以ping www.baidu.com,发现网络其实是通着的),执行ifconfig eth0 down断掉网络(如附图3所示),然后再按Alt + F7恢复图形模式,继续完成向导即可。

    7. 配置好一个安卓虚拟机之后,我们可以直接通过复制多个虚拟磁盘文件android.img,启动多个安卓系统。注意:要指定不同的MAC地址,和不同的VNC端口。

    如附图4和5所示,我配置好一个虚拟机,安装上所需的各种APP之后,通过直接复制android.img,又启动了2个MAC地址不同的安卓模拟器。

    如附图6所示,通过adb远程连接上各安卓虚拟机(模拟器)。
    发布时间:2019-07-10 17:08:14
  • 【经验分享】美团外卖APP在siua头里隐藏了什么信息?
    1. 美团外卖发出的HTTP请求头里有个叫做siua的头(如图1所示),它是什么鬼?
    2.反编译APK,一路跟踪,找到了startCollection(),如图2所示。就是它了。
    3. 通过Xposed HOOK上述函数,成功获取到明文数据(如下所示)。也如图3所示。

    1.0}}MSM8974|Xiaomi|cancro_wc_lte|cancro|KTU84P|zh|CN|Xiaomi|MI 4LTE|4.4.4|19|release-keys|Xiaomi/cancro_wc_lte/cancro:4.4.4/KTU84P/99.12.4:user/release-keys|qcom|qh-miui-ota-bd58|user|cancro|armeabi-v7a|armeabi|cancro-user 4.4.4 KTU84P 99.12.4 release-keys|1|0|}}mtp,adb|mtp,adb|mtp,adb|MPSS.DI.3.0-525eb9a|Qualcomm RIL 1.0|wlan0|ABSENT||1|1|1|1|1|1|1|1|0|1|1|1}}ARMv7 Processor rev 1 (v7l)|Qualcomm MSM8974PRO-AC|4|Accelerometer|STMicroelectronics|Gravity|Qualcomm}}866500021425311|-|-|1920*1080|12GB|12GB|7c:1d:d9:76:af:f9||wifi}}-|0|-1.0|0|0||79d072a8-59fc-4ace-b45e-1b386d8de712}}0|0|0|-}}Android|com.sankuai.meituan.takeoutnew|5.12.3|19|-|2019-06-25 14:00:34:034}}0.0|0.0|KUNZHIPENG|0c:4b:54:da:bd:80|1|-46|-|-|-|}}

    我们来看看这里面包含有什么信息:
    手机品牌、型号、安卓版本号、IMEI码、WLAN的MAC地址、热点名称、热点的MAC地址(如图4所示,和路由器铭牌一致)、手机屏幕尺寸、存储空间...
    发布时间:2019-06-28 16:27:07
  • 【经验分享】如何快速从APK中获取AES秘钥和IV?
    (1)如图1所示,是通过脱壳和反编译获取到的,用时约1小时。
    (2)如图2所示,是使用Xposed + CryptoFucker勾出来的,用时10分钟。
    详细过程见 >>>  http://t.cn/Aip4E9KW ​​​​
    发布时间:2019-06-22 14:21:11
  • 【经验分享】如果动态修改Android设备的代理,如何程序化设置安卓设备的HTTP代理? >>> 详见 http://t.cn/Aip4HUaM ​​​​
    发布时间:2019-06-22 14:11:35
  • 【经验分享】美团外卖APP采集
    1. 如何根据poiId打开店铺详情页?
    adb shell am start -a android.intent.action.VIEW --el poiId 1000651254601802   -n com.sankuai.meituan.takeoutnew/.ui.poi.shop.RestaurantActivity
    效果如图1所示。

    2. 如何截获App返回的应答数据(JSON)?
    使用Xposed勾住parsejson()方法。
    效果如图2所示。
    发布时间:2019-06-20 14:03:02
  • 【经验分享】iostat -d -x -k 1查看某个硬盘的IO一直是100%,如何定位是哪个程序造成的呢? 使用sudo iotop -aoP命令即可,如图所示。 ​​​​
    发布时间:2019-05-29 18:38:49
  • 【经验分享】Apache2如何设置文件的Content-Type值?

    例如,我想给所有的*.pem证书文件,都设置Content-Type为"pplication/x-x509-ca-cert"。
    经查,可以使用ForceType指令,示例如下:

    <FilesMatch "\.pem$">
      ForceType application/x-x509-ca-cert
    </FilesMatch> ​​​​
    发布时间:2019-05-28 15:44:17
  • 【经验分享】如何使用adb检测系统是否安装了某个APP?
    如下所示,判断是否安装了抖音:
    adb shell pm list packages |grep com.ss.android.ugc.aweme ​​​​
    发布时间:2019-05-24 09:39:20
  • 【经验分享】如何破解叮当快药的签名算法? >>> http://t.cn/EoAltBU ​​​​
    发布时间:2019-05-05 17:11:14
  • 【经验分享】抖音的附近功能是根据什么定位的呢?(请求的参数中并没有找到经纬度相关的参数)  经过实测发现是根据IP地址定位的。用西安的代理IP返回的就是西安的,用苏州的代理IP返回就是苏州的,用宿迁的代理IP返回的就是宿迁的。如下截图所示。 ​​​​
    发布时间:2019-04-18 13:42:20
当前位置: 首页 > 技术文章 >
远程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在线客服
欢迎咨询,点击这里给我发送消息。
欢迎咨询,点击这里给我发送消息。

加微信咨询