1.安装
pip3.6 install pyppeteer==0.2.2 -i https://mirrors.aliyun.com/pypi/simple
pyppeteer-install.exe # 安装 chromium 浏览器到 pyppeteer 的默认位置
2.用法 https://miyakogi.github.io/pyppeteer/reference.html 文档说明
pyppeteer-install 第一次运行pyppeteer时,它将下载最新版本的Chromium
3.简单用法
import asyncio
import logging
import os
import time
import tkinter
from lxml import etree
from pyppeteer import launch
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
logging.basicConfig(
level=logging.INFO, # 定义输出到文件的log级别,大于此级别的都被输出
format='%(asctime)s %(filename)s %(levelname)s : %(message)s', # 定义输出log的格式
datefmt='%Y-%m-%d %H:%M:%S', # 时间
filename="{}/qimai_downloads.log".format(BASE_DIR),
filemode='a') # 写入模式“w”或“a”
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# 设置格式
formatter = logging.Formatter('%(asctime)s %(filename)s %(levelname)s : %(message)s')
# 告诉handler使用这个格式
console.setFormatter(formatter)
# 为root logger添加handler
logging.getLogger('').addHandler(console)
class pyppeteerDome(object):
async def intercept_request(self, req):
"""请求过滤"""
if req.resourceType in ['image', 'media', 'eventsource', 'websocket']:
await req.abort()
else:
await req.continue_()
async def intercept_response(self, res):
"""结果过滤"""
resourceType = res.request.resourceType
if resourceType in ['xhr', 'fetch']:
resp = await res.text()
print(resp)
def screen_size(self):
tk = tkinter.Tk()
width = tk.winfo_screenwidth()
height = tk.winfo_screenheight()
tk.quit()
return width, height
async def main(self):
self.browser = await launch(ignoreHTTPSErrors=False, headless=False, dumpio=True, autoClose=False, userDataDir="", args=['--no-sandbox', '--window-size=1920,1080', '--disable-infobars', '--disable-extensions', '--hide-scrollbars', '--disable-bundled-ppapi-flash', '--mute-audio', '--disable-setuid-sandbox', '--disable-gpu', '--log-level=3', '--proxy-server=http://127.0.0.1:8008']) # 进入有头模式
# ignoreHTTPSErrors=False # 是否忽略HTTPS错误。默认为 False
# headless=False # 是否以无头模式运行浏览器
# executablePath (str): 可执行文件的路径,如果指定之后就不需要使用默认的 Chromium 了,可以指定为已有的 Chrome 或 Chromium
# slowMo (int|float): 通过传入指定的时间,可以减缓 Pyppeteer 的一些模拟操作。
# args (List[str]): 在执行过程中可以传入的额外参数。
# ignoreDefaultArgs (bool): 不使用 Pyppeteer 的默认参数,如果使用了这个参数,那么最好通过 args 参数来设定一些参数,否则可能会出现一些意想不到的问题。这个参数相对比较危险,慎用。
# handleSIGINT (bool): 是否响应 SIGINT 信号,也就是可以使用 Ctrl + C 来终止浏览器程序,默认是 True。
# handleSIGTERM (bool): 是否响应 SIGTERM 信号,一般是 kill 命令,默认是 True。
# handleSIGHUP (bool): 是否响应 SIGHUP 信号,即挂起信号,比如终端退出操作,默认是 True。
# dumpio (bool): 是否将 Pyppeteer 的输出内容传给 process.stdout 和 process.stderr 对象,默认是 False。
# userDataDir (str): 即用户数据文件夹,即可以保留一些个性化配置和操作记录。(比如登录信息等;可以在以后打开时自动登录;)
# env (dict): 环境变量,可以通过字典形式传入。
# devtools (bool): 是否为每一个页面自动开启调试工具,默认是 False。如果这个参数设置为 True,那么 headless 参数就会无效,会被强制设置为 False。
# logLevel (int|str): 日志级别,默认和 root logger 对象的级别相同。
# autoClose (bool): 当一些命令执行完之后,是否自动关闭浏览器,默认是 True。
# --proxy-server=http://127.0.0.1:8008 代理
# --start-maximized 最大化窗口
# --no-sandbox 取消沙盒模式 沙盒模式下权限太小
# --disable-infobars 不显示信息栏 比如 chrome正在受到自动测试软件的控制
# --log-level=3 log等级设置 在某些不是那么完整的系统里 如果使用默认的日志等级 可能会出现一大堆的warning信息
# --user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 设置UA
# "userDataDir": "/root" 用户数据保存目录 这个最好也自己指定一个目录
self.page.on('request', self.intercept_request)
self.page.on('response', self.intercept_response)
self.page = await self.browser.newPage() # 打开新的标签页
await self.page.reload() # 获取当前操作的界面重新加载
await self.page.goBack() # 当前操作界面返回
width, height = self.screen_size()
await self.page.setViewport({'width': width, 'height': height}) # 设置页面视图大小
await self.page.setRequestInterception(True)
await self.page.setUserAgent("Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5") # 设置浏览器头
await self.page.setJavaScriptEnabled(enabled=True) # 是否启用JS,enabled设为False,则无渲染效果
await self.page.evaluate('window.scrollBy(0, document.body.scrollHeight)') # 滑动到当前界面底部
# await self.page.setCookie(*cookies) # 设置cookie
# evaluate()是执行js的方法,js逆向时如果需要在浏览器环境下执行js代码的话可以利用这个方法 临时修改浏览器属性中的 webdriver 属性
# await page.evaluate('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')
# 将一段 js 代码加载到页面文档中,当发生页面导航、页面内嵌框架导航的时候加载的 js 代码会自动执行,那么当页面刷新的时候该 js 也会执行,这样就保证了修改网站的属性持久化的目的
await self.page.evaluateOnNewDocument('''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')
# 访问的网站
time.sleep(2) # 等待
# 访问主页 timeout:超时时间
res = await self.page.goto('http://news.baidu.com/', options={'timeout': 100000})
await asyncio.sleep(2) # 等待
print("resp_url:{}".format(self.page.url)) # url
print("resp_headers:{}".format(res.headers)) # 响应头
print("resp_status:{}".format(res.status)) # 响应状态
print("cookies:{}".format(await self.page.cookies())) # 打印页面cookies
print("title:{}".format(await self.page.title())) # 打印当前页标题
print("content:{}".format(await self.page.content())) # 获取所有 html 内容
await self.page.screenshot({'path': './qimai.jpg'}) # 截图保存路径
await self.page.pdf({"path": "./qimai.pdf", "format": 'A4'}) # 保存 PDF
content = etree.HTML(await self.page.content())
data = content.xpath('')[0].strip().replace(':', '')
elements = await self.page.xpath('//*[@id="pane-news"]/div/ul/li/strong/a/@href')
print("*" * 200)
print("elements:{}".format(elements))
for i in elements:
print(i)
await self.page.type(data, "176823035") # 向输入框输入数据
await self.page.click(data) # 鼠标单击某一个元素
await self.page.evaluate(data) # 清空某个input的值
pages = await self.browser.pages() # 获取浏览器打开了几个界面对象
pages[-1] # 获取当前浏览器打开的【最后一个】界面对象
self.page.frames # 获取当前界面中所有的frame对象
time.sleep(1000) # 等待
await self.page.close() # 关闭浏览器
if __name__ == "__main__":
dome = pyppeteerDome()
asyncio.get_event_loop().run_until_complete(dome.main()) # 调用