一些默认属性
import pyppeteer
print('默认版本是:', pyppeteer.__chromium_revision__)
print('可执行文件默认路径:', pyppeteer.chromium_downloader.chromiumExecutable)
print('win64平台下载链接为:', pyppeteer.chromium_downloader.downloadURLs)
print('chrome启动的默认参数:', pyppeteer.defaultArgs())
print('chrome的安装路径:', pyppeteer.executablePath())
简单使用
import asyncio
from pyppeteer.launcher import launch
async def main():
browser = await launch(headless=False)
# 取当前标签页
page = (await browser.pages())[0]
# 新建标签页
# page = await browser.newPage()
await page.waitFor(200)
await page.goto('https://www.baidu.com/')
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
忽略默认参数
不使用默认参数启动浏览器
await launch(headless=False, ignoreDefaultArgs=True)
不使用默认参数中的–enable-automation启动浏览器
await launch(headless=False, ignoreDefaultArgs=["--enable-automation"])
使用自己安装的谷歌浏览器
await launch(headless=False, executablePath="C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe")
设置页面分辨率
await page.setViewport({'width':1440, 'height':900})
启动浏览器时设置默认的:
await launch(headless=False, defaultViewport={"width":1280, "height": 900})
设置UserAgent
await page.setUserAgent("Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Mobile Safari/537.36")
设置浏览器不自动关闭
autoClose=False
async def main():
browser = await launch(headless=False, autoClose=False)
page = (await browser.pages())[0]
print(browser.wsEndpoint)
await page.waitFor(1000)
await page.goto('https://www.baidu.com/')
await browser.disconnect()
重新连接已经存在的浏览器
browser.wsEndpoint
from pyppeteer import connect
async def main():
# 就是上面的browser.wsEndpoint得到的
wsEndpoint = 'ws://127.0.0.1:4344/devtools/browser/16d6ccc9-d1ee-4c2a-ac03-f662c7ece04f'
browser = await connect(browserWSEndpoint=wsEndpoint)
page = (await browser.pages())[0]
await page.waitFor(200)
await page.goto('https://www.weibo.com')
await browser.disconnect()
截图
- 整个页面截图
page.screenshot({'path':'screen.png'})
- 某个元素截图
bgImgie = await page.J(".new-box94")
await bgImgie.screenshot({'path': "1.png"})
元素截图不准的情况(这篇文章看到的):
注:如果通过 element.screenshot() 元素截图有偏差,这是跟电脑分辨率设置有关。
解决:在显示设置 - 将电脑缩放改为100%
执行JavaScript
dimensions = await page.evaluate('''() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
}
}''')
print(dimensions)
获取标签文本和属性
# 获取id="bgImgie"的标签中src属性的值
# //img[@id="bgImgie"]/@src
src = await page.Jeval('img#bgImgie', "node => node.getAttribute('src')")
# //*[@class="question"]/text()
textContent = await page.Jeval('.question', "node => node.textContent")
文档并没有提供直接通过xpath来获取属性的方法,那只能看Jeval的源码,其实就是调用evaluate传入函数字符串(“node => node.textContent”)和elementHandle对象,那么我们也可以调用evaluate传入函数字符串和用xpath定位到的elementHandle对象,代码如下
# 这里用page.Jx('')也可以
elem = await page.waitForXPath('//img[@id="bgImgie"]', {
"timeout":3000} )
# 这个是什么不知道,照抄源码的
document = await page.mainFrame._document()
# 也是照抄源码的,result就是获取的属性
result = await document.executionContext.evaluate("node => node.getAttribute('src')", elem)
最近看到css选择器的用法,发现也挺强大的,之前只会 #id 和.class。现在发现也可以做复杂的提取,具体看:https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building_blocks/Selectors
可以参考: https://blog.csdn.net/Qwertyuiop2016/article/details/124978325
获取cookies
cookies = await page.cookies()
设置cookies
await page.setCookie(*cookies)
# 刷新网页
await page.reload()
如果是浏览器直接复制的cookie字符串,需转为列表
for i in cookies_str.split(';'):
tmp = i.split('=')
cookie = {
"name": tmp[0].strip(), "value": tmp[1].strip()}
cookies.append(cookie)
cookies还有一些其他的值,比如domain、path等,但是只放name和value也是可以用的,需要先访问网站再设置cookie后刷新
鼠标键盘操作
点击标签
await page.click('a#cccccc')
双击
await page.click('a#cccccc', {"clickCount":2})
右键点击
await page.click('a#cccccc',{"button": "right"})
点击坐标
box = await (await page.J('#bgImgie')).boundingBox()
await page.mouse.click(box['x']+box["width"]//2, box['y']+box["height"]//2)
输入文本
page.type('#username', "12345678", {'delay': 50})
鼠标在标签上悬停
await frame.hover('#username')
鼠标按下拖动后松开(可以先悬停)
await page.mouse.down()
await page.mouse.move(2000, 0, {
'delay': 100})
await page.mouse.up()
浏览器启动时访问某个url
async def main():
browser = await launch(headless=False, args=["https://www.baidu.com"])
# 取当前标签页
page = (await browser.pages())[0]
await page.waitFor(3000)
使用代理
http代理
browser = await launch(headless=False, args=["--proxy-server=127.0.0.1:10809"])
或者
browser = await launch(headless=False, args=["--proxy-server=http://127.0.0.1:10809"])
socks代理
browser = await launch(headless=False, args=["--proxy-server=socks5://127.0.0.1:10808"])
有密码的代理
async def main():
browser = await launch(headless=False, args=["--proxy-server=http://127.0.0.1:10809"])
# 取当前标签页
page = (await browser.pages())[0]
await page.waitFor(500)
await page.authenticate({
'username': 'python', 'password': '123456'})
await page.waitFor(500)
await page.goto("https://www.httpbin.org/ip")
使用带密码的socks5代理会报错
Traceback (most recent call last):
File "d:/3.py", line 29, in <module>
loop.run_until_complete(main())
File "C:\Anaconda\envs\test\lib\asyncio\base_events.py", line 608, in run_until_complete
return future.result()
File "d:/3.py", line 16, in main
await page.goto("https://www.httpbin.org/ip")
File "C:\Anaconda\envs\test\lib\site-packages\pyppeteer\page.py", line 879, in goto
raise PageError(result)
pyppeteer.errors.PageError: net::ERR_SOCKS_CONNECTION_FAILED at https://www.httpbin.org/ip
已经用requests验证了这个代理是能正常使用, 谷歌搜了一下确实不支持带验证的socks5代理:https://github.com/puppeteer/puppeteer/issues/4170
如果真要使用带验证的socks5代理,可以利用其它工具转成http代理。介绍一下我比较喜欢的一个工具:gost
使用很简单,下载对应的可执行文件,比如Windows就下载 gost-windows-amd64-2.11.1.zip , 在cmd中执行:gost.exe -L :8686 -F socks5://python:[email protected]:12345
,就将socks5://python:[email protected]:12345
这个代理转发到了本地的8686端口,如果-L
没有指定http和socks类型,两个都可以使用。
browser = await launch(headless=False, args=["--proxy-server=http://127.0.0.1:8686"])
自动化的话可以用Python执行这个命令,不想要内容输出终端的话可以重定向到文件
清理垃圾
pyppeteer会在C:\Users\Administrator\AppData\Local\pyppeteer\pyppeteer\.dev_profile
目录生成一些随机名称的文件夹,时间长了占用很大的空间,建议定期删除。这个目录是--user-data-dir
指定的目录,也可以在启动参数里加--user-data-dir=目录
来指定,这样就不会在dev_profile生成一个随机的目录
其他系统的目录:pyppeteer.__pyppeteer_home__ + os.sep + '.dev_profile'
未完待续
没想到还要啥操作,可以评论说说还有啥