ITPub博客

首页 > 数据库 > 数据库开发技术 > pyppeteer的基本使用

pyppeteer的基本使用

原创 数据库开发技术 作者:kanadeblisst 时间:2019-12-20 11:55:03 0 删除 编辑

前言

本篇博客完全是翻译官方文档,所以如何看得懂英文文档的可以直接看官方文档。文档地址:https://miyakogi.github.io/pyppeteer/

前段时间因为有任务,需要四个电商(京东、淘宝、天猫、拼多多)的数据。而其中京东的没什么反爬,基本是随便抓。拼多多的加密参数有点复杂,而且变化也挺频繁的,用的是selenium,也没什么可提的。抓淘宝和天猫因为用selenium滑块过不了,于是就改成了pyppeteer。现在我说一下使用的心得。有些细节因为当时没有记录,现在也记不起来了。

首先 pip install pyppeteer , 这时候我们先看一下websockets这个库的版本,因为必须保证这个库是7.0的版本。8.0和6.0虽然可以使用,但是在访问多个网页会出现一些无法解决的异常。现在安装pyppeteer,websockets的版本默认是8.0,我们需要先 pip uninstall websockets卸载8.0,然后 pip install websockets==7.0。然后我们按照 https://github.com/miyakogi/pyppeteer/pull/160/files 这个网页修改pyppeteer的源码(如果是anaconda,则路径是 anaconda安装路径\Lib\site-packages\pyppeteer\connection.py这个文件)。这样准备工作就完成了,这样操作之后就可以避免很多异常。其中最常见的一个就是:pyppeteer.errors.NetworkError: Protocol Error (Page.navigate): Session closed. Most likely the page has been closed。

需要这么费劲的折腾,是因为pyppeteer这个库已经很久没有做大的更新了,虽然有点小的改动,但是基本的bug还是没有解决。所以如果有js基础,最好还是使用JavaScript的puppeteer这个工具,这个是谷歌出品的,一直在更新维护,基本没有bug。

补充:有时候会出现明明网页加载完成了,但是还是会出现超时的情况。不知道是什么bug,解决方法也很简单,只要捕获这个异常,然后该做啥做啥。

以下有的方法前面带coroutine这个关键字,有点没有,这是因为带这个参数的方法都是异步方法,这种方法必须被async关键字修饰,调用的时候也必须await关键字修饰。不过我们既然使用浏览器爬虫了,肯定已经不在乎效率了,异步等于在等网站封,所以只需要遵守某些规则即可(不懂的请百度asyncio的使用),实际上还是同步运行。另外,虽然page.on()这个方法是存在的,但是官方文档中并未给出详细的说明,甚至我查看pyppeteer的源码也未找到这个函数,不知道是怎么回事。但是参考puppeteer的文档也是可以用的,不过报错居多,我也就没有深究了。

API参考

启动器

pyppeteer.launcher.launch() 启动chrome进程并返回浏览器实例

参数:

  • ignoreHTTPSErrors(bool):是否忽略HTTPS错误。默认为 False

  • headless(bool):是否在无头模式下运行浏览器。默认为 True除非 appMode或 devtools选项 True

  • executablePath (str):运行Chromium或Chrome可执行文件的路径,而不是默认捆绑的Chromium

  • slowMo (int | float):按指定的毫秒数减慢pyppeteer操作。

  • args (List [str]):传递给浏览器进程的附加参数(标志)。

  • dumpio(bool):是否管道浏览器进程stdout和stderr进入 process.stdout和 process.stderr。默认为 False。

  • userDataDir (str):用户数据目录的路径。

  • env(dict):指定浏览器可见的环境变量。默认与python进程相同。

  • devtools(bool):是否为每个选项卡自动打开DevTools面板。如果是此选项 True, headless则将设置该选项False。

  • logLevel(int | str):用于打印日志的日志级别。默认值与根记录器相同。

  • autoClose(bool):脚本完成时自动关闭浏览器进程。默认为 True。

  • ignoreHTTPSErrors:意思很明显,不解释

  • headless:不解释

  • executablePath:这个一般是默认的路径就行

  • slowMo:我一般会加这个参数,至于效果吗,好像有点。

  • args:常用的有['--no-sandbox','--disable-gpu', '--disable-setuid-sandbox','--window-size=1440x900']

  • dumpio: 不知道为什么,如果不加dumpio=True有时会出现浏览器卡顿

  • userDataDir:selenium的userdata可以保留cookie,下次启动可以达到免登录,而这个参数没什么用

  • env:看需求

  • devtools:用的不深,没用过

  • logLevel:没什么用,在Linux下还是打印大量的日志

  • autoClose:默认就好,不过如果你需要保持浏览器状态,可以不关闭,下次直接连接这个已存在的浏览器

  • loop:暂时不知道有什么用


pyppeteer.launcher.connect() 连接到现有的chrome

参数:

  • browserWSEndpoint(str):要连接的浏览器websocket端点。(必填)

  • ignoreHTTPSErrors(bool):是否忽略HTTPS错误。默认为 False。

  • slowMo (int | float):按指定的毫秒数减慢pyppeteer的速度。

  • logLevel(int | str):用于打印日志的日志级别。默认值与根记录器相同。

  • loop(asyncio.AbstractEventLoop):事件循环

  • browserWSEndpoint:格式是 ws://${host}:${port}/devtools/browser/<id>。以前浏览器的wsEndpoint这个值,可以通过 brower=pyppeteer.launcher.launch() dev=brower.wsEndpoint保存这个值就可以下次启动了


pyppeteer.launcher.executablePath() 获取默认chrome的可执行路径

浏览器类

pyppeteer.browser.Browser() 这个类是由launch()返回的实例

  • browserContexts:返回所有打开的浏览器上下文的列表,在新创建的浏览器中,这将返回单个实例

  • coroutine close():关闭连接并终止浏览器进程

  • coroutine createIncognitoBrowserContext(): 创建一个新的隐身浏览器上下文。这不会与其他浏览器上下文共享cookie /缓存

  • coroutine disconnect(): 断开浏览器

  • coroutine newPage(): 在此浏览器上创建新页面并返回其对象

  • coroutine pages(): 获取此浏览器的所有页面。返回格式为列表,包含所有页面

  • process:返回此浏览器的进程

  • target(): 获取浏览器中所有活动目标的列表

  • coroutine userAgent():返回浏览器的原始UA

  • coroutine version(): 获取浏览器的版本

  • wsEndpoint: 返回websocket端点url

页面类

pyppeteer.page.Page() 由brower.newPage()或者brower.pages()得到

  • coroutine J():别名querySelector(),看名字就知道通过css选择器来选出元素

  • coroutine JJ(): 别名querySelectorAll()

  • coroutine Jeval(): 功能比page.J()功能多一点,可以选出网页文本或者属性指

  • coroutine JJeval(): querySelectorAllEval()

  • coroutine Jx(): 别名xpath()

  • coroutine addScriptTag(): 将脚本标记添加到此页面, 返回ElementHandle

 其中一个url,path或content选择是必要的。

    • url (字符串):要添加的脚本的URL。

    • path (字符串):要添加的本地JavaScript文件的路径。

    • content (字符串):要添加的JavaScript字符串。

    • type(字符串):脚本类型。使用 module以加载一个JavaScript ES6模块。

  • coroutine addStyleTag(): 将样式或链接标记添加到此页面, 返回ElementHandle

 其中一个 url, path或 content选择是必要的。

    • url (字符串):要添加的链接标记的URL。

    • path (字符串):要添加的本地CSS文件的路径。

    • content (字符串):要添加的CSS字符串。

  • coroutine authenticate(): 提供http身份验证的凭据

  • coroutine bringToFront(): 将页面置于前面

  • browser: 获取该页面所属的浏览器

  • coroutine click(): 相当于鼠标左键单击匹配的元素,参数是css选择器的字符串。如果没有匹配到元素,则会引发PageError

可选参数:

    • button(str):,left,right或middle,默认为 left。

    • clickCount (int):默认为1。

    • delay(int | float):等待时间mousedown和 mouseup以毫秒为单位的时间。默认为0。

注意 如果此方法触发导航事件并且存在单独的事件,则waitForNavigation()最终可能会出现产生意外结果的竞争条件。单击并等待导航的正确模式如下:


  1. ```

  2. await asyncio.gather(



  3. page.waitForNavigation(waitOptions),



  4. page.click(selector, clickOptions),



  5. )

  6. ```

大概意思是click()触发如果会跳转网页,则需要page.waitForNavigation()这个函数来等待。但点击事件和触发事件是同时的,所以需要将这两个事件绑定,代码如上。

  • coroutine close(): 关闭此页面

  • coroutine content(): 获取页面的完整HTML内容

  • coroutine cookies(): 获取cookie。参数为URL,如果未指定URL,则此方法返回当前页面URL的cookie。如果指定了URL,则仅返回这些URL的cookie

  • coverage:返回coverage

  • coroutine deleteCookie(): 删除cookie,参数为cookie字段参数,比如name、url、domain、path等

  • coroutine emulate(): 模拟给定的设备指标和用户代理。相当于同时设置了setUserAgent()、setViewport()

  • coroutine emulateMedia(): 模拟页面的css媒体类型。参数为:screen、print、None。

  • coroutine evaluate(): 在浏览器上执行js并获取结果

  • coroutine evaluateHandle(): 同上,只是会返回一个值。至于是什么,没用过

  • coroutine evaluateOnNewDocument(): 也是执行js,至于区别。好像是在页面跳转时执行

  • coroutine exposeFunction(): 将python函数添加到浏览器的window对象中name。不知道有什么用

  • coroutine focus(): 聚焦匹配的元素。如果不存在,抛出PageError

  • frames:获取此页面的所有frame

  • coroutine goBack():返回上一个网页。如果不存在,则返回None

  • coroutine goForward(): 跳转到下一页。如果不存在,则返回None

  • coroutine goto(): 访问某个URL。参数:

    • url:。。。

    • timeout:。。。

    • waitUntil:什么情况下算成功访问。没看懂参数的几个值有什么用

  • coroutine hover(): 鼠标悬停匹配的元素

  • isClosed(): 判断页面是否关闭

  • keyboard:获取keyboard对象

  • mainFrame:获取frame页面的主要内容

  • coroutine metrics(): 好像是获取页面中的信息

  • mouse:获取mouse对象

  • coroutine reload(): 刷新网页

  • coroutine screenshot(): 截图

   参数:

    • x (int):剪辑区域左上角的x坐标。

    • y (int):剪辑区域左上角的y坐标。

    • width (int):剪切区域的宽度。

    • height (int):剪切区域的高度。

    • path(str):保存图像的文件路径。屏幕截图类型将从文件扩展名中推断出来。

    • type(str):指定屏幕截图类型,可以是 jpeg或 png。默认为 png。

    • quality(int):图像的质量,在0-100之间。不适用于 png图像。

    • fullPage(bool):如果为true,请截取完整的可滚动页面。默认为 False。

    • clip(字典):指定页面剪切区域的对象。此选项应包含以下字段:

    • omitBackground (bool):隐藏默认的白色背景并允许捕获具有透明度的屏幕截图。

    • encoding(str):图像的编码可以是 'base64'或 'binary'。默认为 'binary'。

  • coroutine select(): 选择选项并返回所选值。如果未找到元素,抛出ElementHandleError。

  • coroutine setCacheEnabled(): 为每个请求启用/禁用缓存。默认启用

  • coroutine setContent(): 将html加到网页

  • coroutine setCookie(): 设置cookie

  • setDefaultNavigationTimeout(): 更改默认的最大导航超时。默认30秒

  • coroutine setJavaScriptEnabled(): 设置JavaScript启用/禁用

  • coroutine setExtraHTTPHeaders(): 设置默认headers头,值为一个字典

  • coroutine setRequestInterception(): 启用/禁用请求拦截。配合page.on()

  • coroutine setUserAgent(): 设置要在此页面中使用的UA

  • coroutine setViewport(): 设置窗口大小。参数:

    • width (int):以像素为单位的页面宽度。

    • height (int):以像素为单位的页面高度。

    • deviceScaleFactor (float):默认为1.0。

    • isMobile(bool):默认为 False。

    • hasTouch(bool):默认为 False。

    • isLandscape(bool):默认为 False。

  • coroutine tap(): 点击与之匹配的元素

  • coroutine title(): 获取页面标签

  • tracing:获取tracing对象

  • coroutine type(): 往输入框中输入内容,第一个参数为css选择器,第二个为文本内容

  • url:获取此页面的url

  • waitFor(): 等待页面上匹配的函数,超时或元素。参数可以是int或者float,单位毫秒。也可以是css选择器

  • waitForFunction():

  • coroutine waitForNavigation(): 等到网页跳转

  • coroutine waitForRequest(): 等待请求

  • coroutine waitForResponse(): 等待回应

  • waitForSelector(): 等到页面上出现匹配的元素。其实waitFor()也有同样功能。

  • waitForFunction(): 等到函数完成并返回一个值

  • coroutine waitForXPath(): 等到xpath页面上出现匹配的元素

  • workers: 获取页面的所有worker。至于是什么,我不知道

  • coroutine xpath(): ..

worker类

page.on('workercreated', 函数) 这个函数传入的参数就是worker类

  • coroutine evaluate(): 同上

  • coroutine evaluateHandle():同上

  • coroutine executionContext():同上

  • url: 同上

键盘类

  • coroutine down(): 如果没有参数,则是按下鼠标左键。如果是键盘的某个值比如shift、A等键,则是相当于按下这些键。

  • coroutine press(): 同down(),但是上面是不会释放鼠标或者键盘,需要调用up方法释放鼠标。

  • coroutine sendCharacter:将字符发送到页面。没用过

  • coroutine type(): 同上

  • coroutine up(): 释放由down按下的键或者鼠标

鼠标类


  • coroutine click(): 按下(x, y)处的按钮 参数:


    • button(STR):,left(左键)、right(右键)或middle(中键),默认为 left。

    • clickCount (int):默认为1。

    • delay(int | float):等待时间 mousedown和 mouseup以毫秒为单位的时间。默认为0。

  • coroutine down(): 同上

  • coroutine move(): 移动鼠标光标。

  • coroutine up():同上

tracing类

创建可在Chrome DevTools或时间线查看器打开的跟踪文件 ,使用如下

  1. await page.tracing.start({'path': 'trace.json'})



  2. await page.goto('https://www.google.com')



  3. await page.tracing.stop()

  • coroutine start(): 开始跟踪

  • coroutine stop(): 停止跟踪

不好用,可能是我不知道用

Dialog类

page.on('dialog',函数),函数的参数就是这个类

  • coroutine accept(): 接受对话框

  • defaultValue:如果对话框提示,则获取默认提示值

  • coroutine dismiss(): 关闭对话框

  • message: 获取对话框消息

  • type:获取对话框类型。类型有: alert, beforeunload, confirm,或 prompt

frame类

  • coroutine J():同上

  • coroutine JJ():同上

  • coroutine JJeval(): 同上

  • coroutine Jeval(): 同上

  • coroutine Jx(): 同上

  • coroutine addScriptTag(): 同上

  • coroutine addStyleTag(): 同上

  • childFrames: 获取子框架

  • coroutine click(): 同上

  • coroutine content(): 同上

  • coroutine evaluate(): 同上

  • coroutine evaluateHandle(): 同上

  • coroutine executionContext(): 同上

  • coroutine focus(): 同上

  • coroutine hover(): 同上

  • isDetached():如果此框架已分离,则返回True

  • name:获取frame的名称,如果没有则返回ID

  • parentFrame:获取父框架 后面这些属性和page类一模一样

ElementHandle类

  • coroutine J()

  • coroutine JJ()

  • coroutine JJeval()

  • coroutine Jeval()

  • asElement

  • coroutine boundingBox(): 返回此元素的边界框,如果元素不可见,则返回None

  • coroutine boxModel():返回元素框

  • coroutine click()

  • coroutine contentFrame(): 返回元素句柄的frame

  • coroutine focus()

  • coroutine hover()

  • coroutine isIntersectingViewport(): 如果元素在视口中可见,则返回True

  • coroutine press()

  • coroutine screenshot()

  • coroutine tap()

  • coroutine type()

  • coroutine uploadFile(): 上传文件

request类

page.on('request', 函数) 这个函数传入的参数就是request类

  • coroutine abort(): 中断请求

  • coroutine continue_(): 使用可选的请求覆盖继续请求 参数:

    • url (str):如果设置,请求URL将被更改。

    • method(str):如果设置,则更改请求方法(例如 GET)。

    • postData (str):如果设置,则更改发布数据或请求。

    • headers (dict):如果设置,则更改请求HTTP标头

  • failure(): 返回错误文本

  • frame : 返回匹配的frame对象

  • headers: 返回此请求的HTTP标头字典

  • isNavigationRequest(): ??

  • method:返回此请求的方法

  • postData:返回此请求的帖子正文

  • redirectChain:request类重定向的所有请求

  • resourceType:渲染引擎感知的此请求的资源类型

  • coroutine respond(): 通过给定的参数修改请求 参数:

    • status (int):响应状态代码,默认为200。

    • headers (dict):可选的响应头。

    • contentType(str):如果设置,则等于设置 Content-Type 响应头。

    • body (str | bytes):可选的响应主体。

  • response(): 返回匹配的response对象

  • url:此请求的URL

response类

  • buffer(): 返回相应的字节内容

  • fromCache:如果响应是从缓存提供的,则返回True。缓存可能是浏览器的磁盘缓存或者内存,而不是服务器响应的

  • fromServiceWorker:如果响应由服务器提供,则返回True

  • headers:返回此响应的HTTP标头字典

  • coroutine json(): 获取响应正文的JSON

  • ok:返回bool此请求是否成功

  • request:获取匹配的request对象

  • securityDetails:返回与此响应关联的安全详细信息

  • status:响应的状态代码

  • coroutine text(): 获取响应正文的文本

  • url : 响应的URL

target类

我到现在还没明白这是干什么的

  • browser:获取目标所属的浏览器

  • browserContext:返回目标所属的浏览器上下文

  • coroutine createCDPSession(): 创建附加到目标的Chrome Devtools协议会话

  • opener: 获取打开此目标的目标

  • coroutine page(): 获取此目标的页面

  • type: 获取此目标的类型

  • url: 获取此目标的网址

CDPSession类

  • coroutine detach(): 从目标分离会话

  • send() :

Debugging

对于调试,您可以设置for 和 功能 logLevel选项。但是,此选项会打印太多日志,包括pyppeteer的SEND / RECV消息。为了只显示被抑制的错误消息,您应该设置logging.DEBUG为True

  1. import asyncio

  2. import pyppeteer

  3. from pyppeteer import launch



  4. pyppeteer.DEBUG = True # print suppressed errors as error log



  5. async def main():



  6. browser = await launch()



  7. ... # do something



  8. asyncio.get_event_loop().run_until_complete(main())


微信公众号的排版是真的烦。可以点击阅读原文查看我的CSDN博客地址,那个排版就很清楚了。






原文作者:Python成长路;如有侵权,请联系管理员删除。

下一篇: Python下载B站视频
请登录后发表评论 登录
全部评论

注册时间:2019-05-15

  • 博文量
    117
  • 访问量
    67420