什么是puppeteer?
Chrome59(linux、macos)、 Chrome60(windows)之后,Chrome自带headless(无界面)模式很方便做自动化测试或者爬虫。但是如何和headless模式的Chrome交互则是一个问题。通过启动Chrome时的命令行参数仅能实现简易的启动时初始化操作。Selenium、Webdriver等是一种解决方案,但是往往依赖众多,不够扁平。
Puppeteer是谷歌官方出品的一个通过DevTools协议控制headless Chrome的Node库。可以通过Puppeteer的提供的api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。
puppeteer的使用:
目前网上的大多数资料都是基于js进行开发,今天我们剑走偏锋,介绍python中针对该工具开发的第三方工具库pyppeteer,具体的api操作咱就不谈了,官网上有,不咋此赘述,我们直接阐述如何利用pyppeteer做一个远程浏览器服务程序。在该项目考虑到在项目的隔离性,我实在docker容器搭建的该服务端程序,首先首选你需要下载chrome-linux.zip,这是服务端程序必备的工具,好处是他不需要安装,直接解压放在你需要的目录即可(当然也有windows版本chrome-win.zip),其实服务端程序很简单,就一句话打开浏览器,让他一直处于监听状态就行了,就这么简单。二话不说,直接上程序:
#!/usr/bin/env python
# encoding: utf-8
'''
@author: Jonny
@contact: lijinwei@myhexin.com
@software: pycharm
@file: service.py
@time: 2019/7/27 11:25
@desc:puppeteer远程浏览器1
'''
from datetime import datetime
import traceback
import asyncio
from pyppeteer import launch,connect
import log
async def browser_init():
executablePath_linux ="./chrome-linux/chrome"
for _ in range(3):
try:
await launch({
"headless":True,
'executablePath': executablePath_linux,
'args': [
'--disable-gpu=True',
'--disable-dev-shm-usage',
'--disable-setuid-sandbox',
'--no-first-run',
'--no-sandbox',
'--no-zygote',
'--remote-debugging-address=0.0.0.0',
'--remote-debugging-port=9222',
]
})
break
except:
trace = traceback.format_exc().replace("[", "(").replace("]", ")").replace("\n","\t")
log.log(
logname="logs/log_puppeteer_" +datetime.today().strftime("%Y%m%d"),
level="error",
title="browser_init_1",
message="program exeception:" + trace
)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(browser_init())
loop.run_forever()
对于代码不做过多赘述,参考官网api,即可看懂,我们lunch()中的几个字段 :
"headless":True ===> 使用无头模式启动浏览器
args:'--remote-debugging-address=0.0.0.0', '--remote-debugging-port=9222',这两个是自定义绑定服务器端ip地址和端口,方便客户端请求,以获取wsEndpoint.一旦设置了这两个参数,如果你再使用print(browser.wsEndpoint)语句打印wsEndpoint,是不可实现的,所以我们如何在接触不到的服务端程序的时候获取服务端浏览器的长链接地址呢?答案就是:
browserWSEndpoint = requests.get("http://127.0.0.1:19222/json/version").json().get("webSocketDebuggerUrl")
即可拿到所有该浏览器远程操作的所有参数。 当然重点就是wsEndpoint,拿到wsEndpoint后我们可以远程使用下面的函数进行远程连接
import asyncio
import requests
from pyppeteer import launch,connect
async def main(browserWSEndpoint):
global browserWSEndpoin
# Windows 和 Linux 的目录不一样,情换成自己对应的executable文件地址
browser = await connect({"browserWSEndpoint":browserWSEndpoint})
page = await browser.newPage()
await page.goto("https://www.baidu.com/")
content = await page.content()
print(content)
await page.close()
if __name__ == '__main__':
browserWSEndpoint = requests.get("http://127.0.0.1:19222/json/version").json().get("webSocketDebuggerUrl")
print(browserWSEndpoint)
asyncio.get_event_loop().run_until_complete(main(browserWSEndpoint))
至于其他的操作只需要在上面函数中扩展即可 。