基于DevTools协议+Chromium headless的客户端爬虫框架

之前的做法是使用PhantomJS以及一个html+嵌套iframe包含目标网站URL+跨域dom操作的简单性能优化。

PhantomJS实现下面的核心需求:

(1)无头模式,然而PhantomJS内核基于老版本的QtWebKit,与最新版本的Chromium代码相比,版本太老了,很多特性用不了(虽然目前国内网站应该也还没开始用上这些?比如ServiceWorker、CSS
Custom Properties、Web Components等等)

(2)可以等待PhantomJS将页面load完成之后,注入JS执行,这之间需要支持下列核心特性:

2.1 可以通过注入JS代码的方法导入外部JS资源,一般就是动态插入一个<script>元素,并设置src属性;

2.2 可以用注入的JS代码来自动化地控制页面的scroll,或者根据特定网站的代码直接调用相关的JS Event Handler函数

2.3 当然,PhantomJS应该允许从外部直接触发用户输入事件,比如根据某个CSS Selector Path定位到某个Element,然后触发其click事件,浏览器本身通常不支持这么做,但是浏览器的扩展,比如WebDriver这样的原本设计用于自动化Web测试的工具支持这么做

现在的问题是,DevTools支持不支持这些核心需求?

DevTools是一种基于WebSocket通信的协议,请求响应数据都是JSON格式,可以用一个桌面版本的Chrome PC版浏览器连接到手机上的Chrome for Android浏览器进行远程调试,但假如我并不需要这种UI界面呢?这里的客户端爬虫框架需要的是自动化处理,而不是UI+用户交互,DevTools理论上应该是可以支持的,但是可能存在某些限制或使用上的不便,需要进一步进行封装(用NodeJS)?

Check
List:逐一检查DevTools协议支持不支持上面的3个核心特性需求???

Chromium内核中的headless顶级模块好像是从M49版本开始加入的,它提供了多进程的、无头模式的、支持DevTools的自动化支持。

headless模块的编译设置里去除了对于gpu的依赖。(但是不清楚它实现了多大程度上的无头模式???如果真的完全支持的话,照理说应该可以成功编译出一个Windows命令行可执行文件,并且只依赖于网络和文件IO、多线程/IPC这些不需要UI界面参与的系统API)

问题(TODO):

(1)需要Git获取最新版本的Chromium内核代码,并使用新的GN,而不是gyp进行编译

PS:不过我最初设想的客户端爬虫框架是给页面DOM树提供一套新的脚本binding(比如使用Lua),或者也可以实现成一种DSL专用爬虫任务描述语言。这有好处:

(1)不需要用JS写繁琐的代码

(2)页面原生的JS代码完全感觉不到有爬虫在抓取数据的存在,但是外部注入JS的方法理论上避免不了

但是缺点是:

(1)实现难度大,可能需要在内核代码级别做修改,增加一套新的bindings API,但我好像从来没听说过如何bind一个JavaScript以外的脚本语言?

(2)这个新的脚本语言仍然是受限制的:比如说,它不应该修改dom,但是即使如此,考虑到页面原生JS可能正在并发的修改dom,这个地方不能有读写冲突;同时,它应该提供根据某种语法定位元素的API(可以重用CSS Selector的概念);它应该支持dom range对象的定制化的序列化数据导出;同时,它需要允许以编程的方式(脚本自动化)注入用户输入事件,让页面原生JS代码“以为”发生了scroll、gesture、click等UI交互操作。

客户端爬虫也需要能够加载“广告过滤拦截”功能,这个倒是可以在headless代码的基础上修改实现的,但是现有方法html+iframe处理36kr网站的时候就出问题了:它在设置iframe的srcdoc属性为html字符串的时候,过滤掉了所有的<script>元素,这导致页面内容不能正常渲染为dom,原因是36kr现在使用了react.js+json数据来做render。

其实如果直接基于那个json数据来做爬虫数据导出也不是不可以。。。

时间: 2024-11-09 09:26:26

基于DevTools协议+Chromium headless的客户端爬虫框架的相关文章

基于UDP协议的socket编程

UDP协议特点: 1.无连接.服务端与客户端传输数据之前不需要进行连接,且没有超时重发等机制,只是把数据通过网络发送出去.也正是因为此特点,所以基于UDP协议的socket的客户端在启动之前不需要先启动服务端. 2.不可靠.数据在本地通过网络发出之后,UDP协议会立即清除本地的缓存,即使对方没有收到该数据,也不做任何补救措施. 3.数据报协议. 代码示例: 1 import socket 2 server = socket.socket(socket.AF_INET,socket.SOCK_DG

python中基于tcp协议的通信(数据传输)

tcp协议:流式协议(以数据流的形式通信传输).安全协议(收发信息都需收到确认信息才能完成收发,是一种双向通道的通信) tcp协议在OSI七层协议中属于传输层,它上承用户层的数据收发,下启网络层.数据链路层.物理层.可以说很多安全数据的传输通信都是基于tcp协议进行的. 为了让tcp通信更加方便需要引入一个socket模块(将网络层.数据链路层.物理层封装的模块),我们只要调用模块中的相关接口就能实现传输层下面的繁琐操作. 简单的tcp协议通信模板:(需要一个服务端和一个客户端) 服务端: fr

基于http协议的api接口对于客户端的身份认证方式以及安全措施[转]

基于http协议的api接口对于客户端的身份认证方式以及安全措施 由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsessionid)来辨别客户端的身份的,当客户端进行登录服务器也会将登录信息存放在服务器并与客户端的cookie中的jsessionid关联起来,这样客户端再次访问我们就可以识别用户身份了. 但是对于api服务器,我们不能让访问者先登录再进行访问这样不安全,也不友好.所以一般情况我们都是需要客户端提供一个key(每个

android客户端和网站数据交互的实现(基于Http协议获取数据方法)

android客户端一般不直接访问网站数据库,而是像浏览器一样发送get或者post请求,然后网站返回客户端能理解的数据格式,客户端解析这些数据,显示在界面上,常用的数据格式是xml和json. 可以理解客户端其实是一个你自己定义标记语言的浏览器,一般浏览器能解析的是html+css的数据,而android客户端能解析的是xml和json(或者都不是而是你自己定义的火星格式),服务端为了能满足客户端输出这种数据格式的需求,不得不专门针对客户端开发不同于浏览器访问的接口. 开发一个网站的客户端你需

android客户端与服务器交互数据(基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合)

在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,做过JAVA ME的人都知道有KSOAP这个第三方的类库,可以帮助我们获取服务器端webService调用,当然KSOAP已经提供了基于android版本的jar包 首先下载KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包 然后新建android项目 以

基于TCP协议之——socket编程

一. 套接字(socket) socket英文为插座的意思,也就是为用户提供了一个接入某个链路的接口.而在计算机网络中,一个IP地址标识唯一一台主机,而一个端口号标识着主机中唯一一个应用进程,因此"IP+端口号"就可以称之为socket. 两个主机的进程之间要通信,就可以各自建立一个socket,其实可以看做各自提供出来一个"插座",然后通过连接上"插座"的两头也就是由这两个socket组成的socket pair就标识唯一一个连接,以此来表示网

第13章 TCP编程(3)_基于自定义协议的多进程模型

5. 自定义协议编程 (1)自定义协议:MSG //自定义的协议(TLV:Type length Value) typedef struct{ //协议头部 char head[10];//TLV中的T unsigned int checkNum; //校验码 unsigned int cbSizeContent; //协议体的长度 //协议体部 char buff[512]; //数据 }MSG; (2)自定义读写函数 ①extern int write_msg(int sockfd, cha

XMPP协议、IM、客户端互联详解

导读 对于推送,IM服务器,目前可以使用一些厂家提供的SDK来实现,但是我们的老板又总是担心使用别人的SDK,假如别人的服务出现问题,或者别人偷看咱们的信息,那岂不是出现很大问题了 聊一聊xmpp的服务器openfire和测试客户端spark 1.什么是XMPP 这里说一下XMPP,我在前几节说的sdk汇总文章提到的部分推送,IM的SDK提供商用的是XMPP协议,当然也有是自己实现的协议的,例如腾讯.XMPP简单的来说,就是一个发送与接收之间定义的规则,不过这个协议和我们传统的协议有点不同,它不

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1.A2和B2提供服务. Socket概述 ①   所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过“套接字”向网络发出请求或者应答网络请求. ②   Socket是连接运行在网络上的两个程序间的双向通信的端点. ③