首先要解释一下 Headless Chrome,通俗的讲就是运行一个没有GUI的Chrome,在 Headless Chrome 出现以前有 PhantomJS ,但是自从 Headless Chrome 出现之后 PhantomJS 活跃度下降,所以维护者就宣布 了停止继续开发。那么 Headless Chrome 能够什么呢?自动化测试,网页截图,网络调试,爬虫等等任务。Google 说在可预见的未来会一直维护。

关于 Headless Chrome 官方有两篇教程

在 Headless Chrome 之前使用 Python 可以结合Chrome推出的 chromedriver 来操作 PhantomJS,那么现在有了Chrome的Headless模式怎么来控制Chrome就是这篇文章要讲的内容。

Chrome DevTools Protocol

在此之前几个重要的网址:

Google官方维护了一份协议叫做 Chrome DevTools Protocol,只要是实现了这一份协议就能够编程来控制Chrome,Chrome 自带的开发者工具其实也是这一份协议的实现。

Browser 实例可以拥有多个 Page

Page 拥有至少一个 frame: main frame, 其他的 frame 可能被网页标记 iframe 和 frame 创建

Frame 拥有一个可执行的上下文,在该上下文中 JavaScript 可以被执行,Frame 中也可能有浏览器扩展 extensions 产生的内容被执行

可以用这张图 来显示其结构。

常用API

Browser 浏览器版本,关闭,命令行等等管理操作

Page 该域包含和页面相关接口,页面加载,资源内容,截图,打印等

Network 网络请求,Cookie,缓存,证书等内容

DOM 文档DOM的获取,修改,删除等

Runtime 该域下暴露 JavaScript 相关运行时接口,可以用来执行代码

本地启动 Headless Chrome

本地启动 Headless Chrome 可以参考这篇文章。

如果需要使用 Docker 来启动Headless Chrome 也可以使用

docker run -it --rm --name alpine-chrome -p 9222:9222 einverne/alpine-chrome

更加具体的使用介绍可以查看 GitHub

pychrome

pychrome 是 Chrome Devtools Protocol 的 Python 实现,其他语言的实现,可以查看这个项目。Chrome官方推荐js/nodejs的实现 chrome-remote-interface 还有 node.js 实现的更高层级的 Puppeteer。

这里主要摘录几个常用的操作

截图

使用 Page.captureScreenshot

def screenshot(browser, url, filename='image.png'):

tab = browser.new_tab()

tab.start()

tab.call_method('Page.navigate', url=url, _timeout=5)

tab.wait(10)

# 截取当前Tab屏幕,结果为图片内容Base64

screen_base64 = tab.call_method("Page.captureScreenshot")

image_data = screen_base64.get('data', '')

with open(filename, 'wb') as f:

f.write(image_data.decode('base64'))

tab.stop()

browser.close_tab(tab)

打印PDF

同样使用 Page 下方法

def print_to_pdf(browser, url, filename='file.pdf'):

tab = browser.new_tab()

tab.start()

tab.call_method('Page.navigate', url=url, _timeout=5)

tab.wait(10)

pdf_data = tab.call_method('Page.printToPDF', landscape=False).get('data')

with open(filename, 'wb') as f:

f.write(pdf_data.decode('base64'))

tab.stop()

browser.close_tab(tab)

向下翻页

def perform_input(browser):

"""向下浏览页面"""

tab = browser.new_tab()

tab.start()

tab.Page.enable()

tab.Page.navigate(url='https://www.douban.com/', _timeout=5)

tab.wait(5)

# 更多 keycode 可以参考 https://msdn.microsoft.com/en-us/library/dd375731(VS.85).aspx

keycode = int(0x22)

tab.Input.dispatchKeyEvent(type='keyDown', windowsVirtualKeyCode=keycode, nativeVirtualKeyCode=keycode)

tab.wait(3)

screen_base64 = tab.call_method("Page.captureScreenshot")

image_data = screen_base64.get('data', '')

with open("keyDown.png", 'wb') as f:

f.write(image_data.decode('base64'))

tab.stop()

browser.close_tab(tab)

获取网页HTML

获取动态网页的网页内容,等待JS执行完成后获取HTML

def get_html(browser, url):

tab = browser.new_tab()

tab.start()

tab.call_method('Page.navigate', url=url, _timeout=5)

tab.wait(10)

html = tab.Runtime.evaluate(expression="document.documentElement.outerHTML")

tab.stop()

browser.close_tab(tab)

return html['result']['value']

操纵网页元素注入JS

下面这段代码是访问 baidu,输入关键字,并点击搜索按钮,解析搜索结果并打印

def perform_click(browser):

tab = browser.new_tab()

# def loading_finished(**kwargs):

# print "[loading finished]"

#

# # when HTTP request has finished loading

# tab.set_listener("Network.loadingFinished", loading_finished)

tab.start()

# call method

# tab.Network.enable()

tab.Network.enable()

tab.Page.enable()

tab.Runtime.enable()

def dom_content_event_fired(**kwargs):

print "[content] dom content event fired"

tab.DOM.enable()

root = tab.DOM.getDocument()

root_node_id = root.get('root', {}).get('nodeId', '')

# 找到输入框

input_box = tab.DOM.querySelector(nodeId=root_node_id, selector='#kw')

# tab.DOM.setNodeValue(nodeId=input_box, value='hello')

tab.Runtime.evaluate(expression='document.getElementById("kw").value="Chrome"', )

# 找到搜索按钮

search_btn = tab.DOM.querySelector(nodeId=root_node_id, selector='#su')

remote_node = tab.DOM.resolveNode(nodeId=search_btn.get('nodeId', ''))

# 执行点击

tab.Runtime.callFunctionOn(functionDeclaration='(function() { this.click(); })',

objectId=remote_node.get('object', {}).get('objectId', {}))

tab.wait(3)

# 输出结果

html = tab.Runtime.evaluate(expression="document.documentElement.outerHTML")

html_value = html.get('result', {}).get('value', '').encode('utf-8')

soup = BeautifulSoup(html_value, 'html.parser')

l = soup.select('h3 > a')

for result in l:

print result.text

print result['href']

screen_base64 = tab.call_method("Page.captureScreenshot")

image_data = screen_base64.get('data', '')

with open("test.png", 'wb') as f:

f.write(image_data.decode('base64'))

# tab.DOM.performSearch(query='xpath', includeUserAgentShadowDOM=True)

# stop the tab (stop handle events and stop recv message from chrome)

tab.stop()

# close tab

browser.close_tab(tab)

tab.set_listener("Page.domContentEventFired", dom_content_event_fired)

# tab.call_method("Page.reload", ignoreCache=False)

tab.call_method("Page.navigate", url='https://www.baidu.com', _timeout=5)

tab.wait(20)

完整的代码可以参考 GitHub

其他可学习的网站

这篇文章讲述了使用 nodejs 的库 NickJS来爬取网站的要点。

这篇使用 nodejs 的chrome-remote-interface,来抓取网页。

其他

https://stackoverflow.com/questions/28430479/using-google-chrome-remote-debugging-protocol

https://blog.phantombuster.com/web-scraping-in-2017-headless-chrome-tips-tricks-4d6521d695e8

https://stackoverflow.com/questions/7848878/how-to-use-google-chrome-remote-debugging-protocol-in-http

https://github.com/auchenberg/devtools-remote

https://github.com/auchenberg/chrome-devtools-app

https://intoli.com/blog/running-selenium-with-headless-chrome

https://duo.com/blog/driving-headless-chrome-with-python

python chrome headless_使用Python控制Headless Chrome相关推荐

  1. 初探 Headless Chrome

    2019独角兽企业重金招聘Python工程师标准>>> 什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览 ...

  2. PuppeteerSharp: 更友好的 Headless Chrome C# API

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

  3. Puppeteer -headless Chrome 的 Node.js API

    Puppeteer 是一个控制 headless Chrome 的 Node.js API .它是一个 Node.js 库,通过 DevTools 协议提供了一个高级的 API 来控制 headles ...

  4. Web自动化之Headless Chrome概览

    Web自动化 这里所说的Web自动化是所有跟页面相关的自动化,比如页面爬取,数据抓取,页面内容检测,页面功能测试,页面加载性能测试,页面回归测试等等,当前主要由如下几种解决方式: 文本数据获取 这就是 ...

  5. python chrome headless_[技巧] chrome headless 爬虫抓取websoket 数据

    目录 源起 分析 实践 总结 源起 周末答应了一个朋友帮他看一下一个网站应该怎么爬,费话不说直接先上网站 https://datacenter.jin10.com/price 数据一直在不停的闪,直觉 ...

  6. python chrome headless_实战Chrome Headless数据抓取(上)

    先聊聊数据抓取技术选型 在我看来数据抓取可以分为三种场景: 基本稳定的源站格式或者大量的数据抓取.需要蜘蛛集群调度:使用Java比较方便,可以用WebMagic抓取配合Hadoop调度,如果源站经常改 ...

  7. 用Python驱动Headless Chrome

    Headless Browser(无头的浏览器)是什么鬼? 简而言之,Headless Browser是没有图形用户界面(GUI)的web浏览器,通常是通过编程或命令行界面来控制的. Headless ...

  8. 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法

    by Joyz 通过乔伊斯 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法 (A recipe for website automated ...

  9. 【Python小技巧】Python操控Chrome浏览器实现网页打开、切换、关闭(送独家Chrome操作打包类源码、Chrome浏览器Cookie在哪里?)

    文章目录 前言 一.什么时候需要用Python控制浏览器? 二.下载Chrome浏览器驱动文件 1. 安装Chrome浏览器并查看版本 2. 下载浏览器驱动文件 3. 解压到python编译器目录(p ...

最新文章

  1. 四因素三水平正交试验表_案例 | 螺栓装配失效试验研究
  2. 车牌识别中的可识性、放弃率、精度与识别率辨析
  3. React开发(267):ant design upload简单上传
  4. java类可选,java – 是否有类可选,但非可选的类?
  5. 普通人学python有意义吗_学python难吗
  6. 推荐一个强大的Go库-rk-boot,未来 Go领域的SpringBoot?
  7. 电脑主板跳线_DIY电脑主板的跳线安装及排序规则
  8. 华为发布全新5G芯片:天罡和巴龙5000
  9. Intel XDK问题
  10. MASK RCNN在tensorflow 2.5中运行
  11. pr cpu100%_PR插件Sapphire2019.52安装教程
  12. 产品经理简历怎么写?看这一篇就够了
  13. 数据库课程设计-NBA球队信息管理系统
  14. 日常思维方法:演绎法 归纳法
  15. 合同在项目管理中的优势
  16. 小米mix2安兔兔html5跑分,vivo X21跑分多少?高通骁龙660 AIE安兔兔跑分实测
  17. 悉尼大学高级计算机专业世界排名,悉尼大学专业排名一览及最强专业推荐(QS世界大学排名)...
  18. 我为什么要表扬深信服(转)
  19. react实现上传文件进度条功能_js上传文件(可自定义进度条)
  20. uni-app 苹果登录

热门文章

  1. 异常检测主要方法总结
  2. 删除的备忘录内容怎么恢复?
  3. Android xUtils框架解析
  4. JAVA基础11 网络编程
  5. switch和for循环的案例
  6. 【合集】高等数学:繁星随想录
  7. 电脑主板没有无线网卡怎么上网?怎么通过usb共享网络?
  8. 定义一个函数,输入三角形的三条边,求三角形面积
  9. 多米尼加共和国商标注册概要和审查
  10. 第七届杭州全球企业家论坛大健康分论坛即将举办,敬请关注!