文档章节

实战Chrome Headless数据抓取(上)

打雷要下雨LEO
 打雷要下雨LEO
发布于 2017/05/01 15:59
字数 1811
阅读 12099
收藏 32

先聊聊数据抓取技术选型

在我看来数据抓取可以分为三种场景:

  • 基本稳定的源站格式或者大量的数据抓取、需要蜘蛛集群调度:使用Java比较方便,可以用WebMagic抓取配合Hadoop调度,如果源站经常改动用Java代码实现页面分析真的很蛋疼。
  • 常规的一般页面抓取:使用Python妥妥的,脚本语言改动灵活,代码简单,而且相关类库很多。
  • 比较难抓的,有较强反扒措施的网站,比如网银和现在比较流行的Vue、React:这些网站有的有浏览器插件,有的js和html混写,很难静态分析再模拟请求。只能使用真实的浏览器引擎动态解析页面。

本文说的Chrome headless就是针对比较难抓取的情况提出的一种新的解决方案。 将Chrome以无界面模式运行,开启Chrome Remote Debugging,从外部进入Chrome内。之前有类似的PhantomJS、Selenium之类的东西,相比来说直接用原生Chrome兼容性更强,更通用。缺点都是抓取效率较低,动态抓取需要将页面执行一遍再操作DOM抓取,不如模拟请求快。

环境搭建

Chrome从59版开始支持headless模式运行,不考虑Chromium,Chrome有四种版本:

  • Stable 稳定版,最新版本:58
  • Beta 测试版,最新版本:59
  • Dev 开发版,最新版本:60
  • Canary 金丝雀,最新版本:60(每天更新,只有Windows版)

如果你在本机开发,推荐使用Canary,它和已有的Chrome不在同一目录下,可以共存。

我这里配了一台Ubuntu Server虚拟机,注意Server版即可,不需要桌面环境。然后安装了Chrome dev版。Ubuntu安装Chrome参考:https://segmentfault.com/a/1190000007895508 。 如果像我一样在虚拟机或远程服务器上,安装完把9222端口映射出来(起初我直接防火墙放开了9222端口的访问,但是死活连不上,可能Chrome远程调试限制了请求的IP只能是本机),我用的ssh访问的虚拟机,所以直接用ssh把端口转发出来,不详述了。

关于Chrome Debugging Protocol

Chrome提供了websocket调试接口用于对当前Tab内页面的DOM、网络、性能、存储等等进行调试,我们常用的开发者工具就是基于此接口,这个接口也支持远程调用,在启动参数中加上--remote-debugging-port=9222即可。

Chrome开发者工具

远程调试还提供了一个JSON接口,用于管理浏览器的Tab页面。

跑起来

启动Chrome

如果在远程服务器上建议在screen里运行,一个小工具防止网络突然中断。

$ screen -S chrome

然后会打开一个新的shell,可以用 Ctrl + A + D切出来,或者断开SSH直接切出来。再进去只需要执行:

$ screen -r chrome

然后在screen里面的shell执行(本机Windows调试把google-chrome-unstable换成chrome.exe):

$ google-chrome-unstable --headless --remote-debugging-port=9222 --user-data-dir='/home/luke/chrome-data/baidu' --user-agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3080.5 Safari/537.36'

解释下参数:

  • --headless:无头模式,就是无界面模式运行
  • --remote-debugging-port:开启远程调试,端口9222和我们之前转发出来的端口一致
  • --user-data-dir:设置独立的文件保存目录,建议一个网站一个目录
  • --user-agent:伪装浏览器,默认User-Agent里的浏览器叫HeadlessChrome,很容易被发现

连接调试端口

我们说过远程调试接口是一个WebSocket的接口,Chrome提供的开发者工具是一种客户端,我们自己写代码调用也是一种客户端。今天我们先用开发者工具测试,下篇我会写代码来实现。 在本地浏览器打开:http://服务器IP:9222/json ,本机测试的话就是 http://127.0.0.1:9222/json 。我已经用SSH把服务器的9222转发到本机的9222了,这是效果:

连接调试端口

这里列出了当前远程浏览器内打开的Tab,每个页面一个UUID用以识别。已知接口:

抓取百度

远程打开

我们新开一个Tab打开百度首页,然后刷新Tab列表,可以看到百度已经打开了:

百度Tab

注意到,有一个devtoolsFrontendUrl,那就是开发者工具的前端地址,就是一个html应用,url里面传过去WebSocket调试地址。打开这个地址就可以看到熟悉的开发者工具了!注意:这个窗口调试的是远程chrome上的页面。

百度首页

如果你想看看页面在远程服务器的Chrome里渲染的结果,在开发者工具里切换到Performance,勾选Screenshots,点刷新图标,重新加载完成就可以看到逐帧加载的截图。

远程操作DOM

思路:我们在Elements里面找到输入框的ID,使用JQuery操作。百度首页已经有JQuery了,其他网站我们可以在Console里执行JS,加载一个。 我们切换到Console里直接用JS操作DOM,执行:

$("input[name='wd']").val('测试');
$("form.fm").submit();

相当于在百度输入框里输入了测试并点击了“百度一下”按钮。

JS操作DOM

现在再打开http://127.0.0.1:9222/json ,可以看到原来的页面标题已经变成了“测试_百度搜索”,也就说明成功完成了搜索。

获取搜索结果

依然是在Elements里面找到结果列表的ID,然后用JS获取内容。 获得结果数量:

console.log($("#container").find(".nums").text());

获得所有结果标题:

$("#container").find(".c-container").each(function(){console.log($(this).find("h3.t").text())});

获取搜索结果

获取其他内容都一样,不再演示。

总结

这篇文章展示了调用远程Headless模式的Chrome做页面抓取,也可以用来做自动化测试,另外对于Android版Chrome同样支持远程调试!下篇文章将通过代码直接调用WebSocket接口。

一些提示

  • 用JQuery操作远程页面DOM可以先在本机打开目标页面做调试,用元素选取器更方便快速定位DOM。
  • Server版Ubuntu一般没有中文字体,看到的远程截图中文都是方块,但是我们也不需要截图,有需要请自行安装Windows上的字体以保持一致性。

参考链接

© 著作权归作者所有

打雷要下雨LEO
粉丝 11
博文 13
码字总数 4328
作品 0
深圳
程序员
私信 提问
加载中

评论(5)

子鱼不是鱼
子鱼不是鱼

引用来自“子鱼不是鱼”的评论

你好,我也是虚拟机的ubuntu server上安装了chrome,本机是windows,请问怎么端口转发,我各种百度google试了两天了都不成功啊,防火墙9222端口也放开了啊

引用来自“打雷要下雨LEO”的评论

可能不是防火墙的问题,chrome加个启动参数试试: --remote-debugging-address=0.0.0.0
哦,好了。
多谢了
打雷要下雨LEO
打雷要下雨LEO 博主

引用来自“子鱼不是鱼”的评论

你好,我也是虚拟机的ubuntu server上安装了chrome,本机是windows,请问怎么端口转发,我各种百度google试了两天了都不成功啊,防火墙9222端口也放开了啊
可能不是防火墙的问题,chrome加个启动参数试试: --remote-debugging-address=0.0.0.0
子鱼不是鱼
子鱼不是鱼
你好,我也是虚拟机的ubuntu server上安装了chrome,本机是windows,请问怎么端口转发,我各种百度google试了两天了都不成功啊,防火墙9222端口也放开了啊
子鱼不是鱼
子鱼不是鱼
nihao
javadeveloper
javadeveloper
挺好,期待更多实战讲解。
PuppeteerSharp: 更友好的 Headless Chrome C# API

前端就有了对 headless 浏览器的需求,最多的应用场景有两个 UI 自动化测试:摆脱手工浏览点击页面确认功能模式 爬虫:解决页面内容异步加载等问题 也就有了很多杰出的实现,前端经常使用的莫...

张善友
03/09
0
0
无需密码即可窃取 Chrome 的 Cookie

简评:如果你想窃取别人 Chrome Cookie,通常需要你输入用户的密码来完成这项工作。这篇教程介绍如何不需要密码直接获取用户的 cookie。 如果只是想要直接使用这个工具可以移步到 https://gi...

极小光
2018/11/12
0
0
zg手册 之 scrapy 开发(4)-- javascript 动态页面的抓取

javascript 动态页面 目前许多网站大量运用js脚本进行一些页面的处理,这些页面的抓取对爬虫是个挑战。 这类页面的抓取,我用到了下面的方法 分析页面(firebug/chrome调试工具 等),找到a...

东昕
2014/04/02
985
2
puppeteer+mysql—爬虫新方法!抓取新闻&评论so easy!

Puppeteer 是 Google Chrome 团队官方的无界面(Headless)Chrome 工具。正因为这个官方声明,许多业内自动化测试库都已经停止维护,包括 PhantomJS。Selenium IDE for Firefox 项目也因为缺...

圆儿圈圈
2018/09/17
0
0
函数计算中使用 puppeteer.js

puppeteer.js github 地址:https://github.com/GoogleChrome/puppeteer API: https://github.com/GoogleChrome/puppeteer/blob/v1.4.0/docs/api.md 函数计算文档:https://help.aliyun.com......

木香丘
2018/06/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
今天
12
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
4
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.3K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部