pyppeteer的一些使用

2022-07-27 08:49:25

一些默认属性

import pyppeteerprint('默认版本是:', pyppeteer.__chromium_revision__)print('可执行文件默认路径:', pyppeteer.chromium_downloader.chromiumExecutable)print('win64平台下载链接为:', pyppeteer.chromium_downloader.downloadURLs)print('chrome启动的默认参数:', pyppeteer.defaultArgs())print('chrome的安装路径:', pyppeteer.executablePath())

简单使用

import asynciofrom pyppeteer.launcherimport launchasyncdefmain():
    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

asyncdefmain():
    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 pyppeteerimport connectasyncdefmain():# 就是上面的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()

截图

  1. 整个页面截图
    page.screenshot({'path':'screen.png'})
  2. 某个元素截图
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 iin 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

asyncdefmain():
    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"])

有密码的代理

asyncdefmain():
    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", line29,in<module>
    loop.run_until_complete(main())
  File"C:\Anaconda\envs\test\lib\asyncio\base_events.py", line608,in run_until_completereturn future.result()
  File"d:/3.py", line16,in mainawait page.goto("https://www.httpbin.org/ip")
  File"C:\Anaconda\envs\test\lib\site-packages\pyppeteer\page.py", line879,in gotoraise 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:123456@127.0.0.1:12345,就将socks5://python:123456@127.0.0.1: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'

未完待续

没想到还要啥操作,可以评论说说还有啥

  • 作者:Qwertyuiop2016
  • 原文链接:https://blog.csdn.net/Qwertyuiop2016/article/details/122698409
    更新时间:2022-07-27 08:49:25