【Puppeteer概要】

  • Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。 Puppeteer API 是分层次的,反映了浏览器结构。
  • Puppeteer 使用 DevTools 协议 与浏览器进行通信。
  • Browser 实例可以拥有浏览器上下文。
  • BrowserContext 实例定义了一个浏览会话并可拥有多个页面。
  • Page 至少有一个框架:主框架。 可能还有其他框架由 iframe 或 框架标签 创建。
  • frame 至少有一个执行上下文 - 默认的执行上下文 - 框架的 JavaScript 被执行。 一个框架可能有额外的与 扩展 关联的执行上下文。
  • Worker 具有单一执行上下文,并且便于与 WebWorkers 进行交互。

【Puppeteer 错误处理】

Error handling

  • 如果 Puppeteer 方法无法执行一个请求,就会抛出一个错误。例如,page.waitForSelector(selector[, options]) 选择器如果在给定的时间范围内无法匹配节点,就会失败。 对于某些类型的错误,Puppeteer 使用特定的错误类处理。这些类可以通过 require('puppeteer/Errors') 获得。 支持的类列表:

TimeoutError 一个处理超时错误的例子:

const {
    TimeoutError
} = require('puppeteer/Errors'); // ...
try {
    await page.waitForSelector('.foo');
} catch(e) {
    if (e instanceof TimeoutError) {  
    // 如果超时,做一些处理。 
    }
}

Puppeteer Working with Chrome Extensions

  • Puppeteer 可以用来测试 Chrome 扩展

注意 Chrome / Chromium 扩展当前只能在非无头模式下使用。

下面的代码用来处理扩展的 background page,该扩展的代码在 ./my-extension:

const puppeteer = require('puppeteer'); (async() = > {
const pathToExtension = require('path').join(__dirname, 'my-extension');
const browser = puppeteer.launch({
    headless: false,
    args: [`--disable - extensions - except = $ {
        pathToExtension
    }`, `--load - extension = $ {
        pathToExtension
    }`]
});
const targets = await browser.targets();
const backgroundPageTarget = targets.find(target = >target.type() === 'background_page');
const backgroundPage = await backgroundPageTarget.page(); // 像处理任何其他页面一样测试背景页面。  await browser.close();})();

【Puppeteer class:puppeteer】

  • Puppeteer 模块提供了一种启动 Chromium 实例的方法。 下面就是使用 Puppeteer 进行自动化的一个典型示例:
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser = >{
const page = await browser.newPage();
await page.goto('https://www.google.com'); // 其他操作...  await browser.close();});

Methods

  • puppeteer.connect(options)v0.9.0
  • puppeteer.createBrowserFetcher([options])v0.9.0
  • puppeteer.defaultArgs([options])v0.9.0
  • puppeteer.executablePath()v0.9.0
  • puppeteer.launch([options])v0.9.0

Methods

puppeteer.connect(options)v0.9.0

  • options <Object>
  • browserWSEndpoint <string> 一个 浏览器 websocket 端点链接。
  • ignoreHTTPSErrors <boolean> 是否在导航期间忽略 HTTPS 错误. 默认是 false。
  • defaultViewport <?Object> 为每个页面设置一个默认视口大小。默认是 800x600。如果为 null 的话就禁用视图口。
  • width <number> 页面宽度像素。
  • height <number> 页面高度像素。
  • deviceScaleFactor <number> 设置设备的缩放(可以认为是 dpr)。默认是 1。
  • isMobile <boolean> 是否在页面中设置了 meta viewport 标签。默认是 false。
  • hasTouch``<boolean> 指定viewport是否支持触摸事件。默认是 false。
  • isLandscape <boolean> 指定视口是否处于横向模式。默认是 false。
  • slowMo <number> 将 Puppeteer 操作减少指定的毫秒数。这样你就可以看清发生了什么,这很有用。
  • returns: <Promise<Browser>> 此方法将 Puppeteer 添加到已有的 Chromium 实例。

puppeteer.createBrowserFetcher([options])v0.9.0

  • options <Object>
  • host <string> 要使用的下载主机. 默认是 https://storage.googleapis.com。
  • path <string> 下载文件夹的路径. 默认是 <root>/.local-chromium, <root> 是 puppeteer 的包根目录。
  • platform <string> 可能的值有: mac, win32, win64, linux。默认是当前平台
  • returns: <BrowserFetcher>

puppeteer.defaultArgs([options])v0.9.0

  • options <Object> 设置浏览器可选项。有一下字段:
  • headless <boolean> 是否在 无头模式 下运行浏览器。默认是 true 除非 devtools 选项是 true。
  • args <Array<string>> 传递给浏览器实例的其他参数。可以 在这 找到 Chromium 标志列表。
  • userDataDir <string> 用户数据目录 的路径。
  • devtools <boolean> 是否为每个选项卡自动打开 DevTools 面板。如果这个选项是 true 的话, headless 选项将被设置为 false。
  • returns: <Array<string>> Chromium 启动时使用的默认参数。

puppeteer.executablePath()v0.9.0

  • returns: <string> Puppeteer 希望找到绑定的 Chromium 的路径。
  • 如果使用 PUPPETEER_SKIP_CHROMIUM_DOWNLOAD 跳过下载,则 Chromium 可能不存在。

puppeteer.launch([options])v0.9.0

  • options <Object> 在浏览器上设置的一组可配置选项。 有以下字段:
  • ignoreHTTPSErrors <boolean> 是否在导航期间忽略 HTTPS 错误. 默认是 false。
  • headless <boolean> 是否以 无头模式 运行浏览器。默认是 true,除非 devtools 选项是 true。
  • executablePath <string> 可运行 Chromium 或 Chrome 可执行文件的路径,而不是绑定的 Chromium。如果 executablePath 是一个相对路径,那么他相对于 当前工作路径 解析。
  • slowMo <number> 将 Puppeteer 操作减少指定的毫秒数。这样你就可以看清发生了什么,这很有用。
  • defaultViewport <?Object> 为每个页面设置一个默认视口大小。默认是 800x600。如果为 null 的话就禁用视图口。
  • width <number> 页面宽度像素。
  • height <number> 页面高度像素。
  • deviceScaleFactor <number> 设置设备的缩放(可以认为是 dpr)。默认是 1
  • isMobile <boolean> 是否在页面中设置了 meta viewport 标签。默认是 false。
  • hasTouch``<boolean> 指定viewport是否支持触摸事件。默认是 false。
  • isLandscape <boolean> 指定视口是否处于横向模式。默认是 false。
  • args <Array<string>> 传递给浏览器实例的其他参数。 这些参数可以参考 这里。
  • ignoreDefaultArgs <(boolean|<Array<string>>)> 如果是 true,那就不要使用 puppeteer.defaultArgs()。 如果给出了数组,则过滤掉给定的默认参数。这个选项请谨慎使用。默认为 false
  • handleSIGINT <boolean> Ctrl-C 关闭浏览器进程。默认是 true
  • handleSIGTERM <boolean> 关闭 SIGTERM 上的浏览器进程。默认是 true
  • handleSIGHUP <boolean> 关闭 SIGHUP 上的浏览器进程。默认是 true.
  • timeout <number> 等待浏览器实例启动的最长时间(以毫秒为单位)。默认是 30000 (30 秒). 通过 0 来禁用超时。
  • dumpio <boolean> 是否将浏览器进程标准输出和标准错误输入到 process.stdout 和 process.stderr 中。默认是 false。
  • userDataDir <string> 用户数据目录 路径。
  • env <Object> 指定浏览器可见的环境变量。默认是 process.env
  • devtools <boolean> 是否为每个选项卡自动打开DevTools面板。如果这个选项是 true,headless 选项将会设置成 false
  • pipe <boolean> 通过管道而不是WebSocket连接到浏览器。默认是 false
  • returns: <Promise<Browser>> 浏览器实例支持 Promise

这个方法结合了下面3个步骤:

使用 puppeteer.defaultArgs() 作为一组默认值来启动 Chromium。

启动浏览器并根据 executablePathhandleSIGINTdumpio 和其他选项开始管理它的进程。 创建一个 Browser 类的实例,并根据 defaultViewportslowMoignoreHTTPSErrors 初始化它。 ignoreDefaultArgs 选项可用于自定义(1)步骤的行为。 例如,要从参数中过滤掉 --mute-audio

const browser = await puppeteer.launch({
    ignoreDefaultArgs: ['--mute-audio']
});
复制代码

Puppeteer 浏览器

  • extends: EventEmitterPuppeteer 连接到一个 Chromium 实例的时候会通过 puppeteer.launchpuppeteer.connect 创建一个 Browser 对象。 下面是使用 Browser 创建 Page 的例子
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser = >{
const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();
});
  • 一个断开连接和重连到 Browser 的例子:
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser = >{ // 存储节点以便能重新连接到 Chromium  
const browserWSEndpoint = browser.wsEndpoint();  // 从 Chromium 断开和 puppeteer 的连接  browser.disconnect();  // 使用节点来重新建立连接  
const browser2 = await puppeteer.connect({browserWSEndpoint});  // 关闭 Chromium  
await browser2.close();});

Puppeteer 页面

  • Page 提供操作一个 tab 页或者 extension background page 的方法。一个 Browser 实例可以有多个 Page 实例。 下面的例子创建一个 Page 实例,导航到一个 url ,然后保存截图:
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser = >{
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await page.screenshot({
        path: 'screenshot.png'
    });
    await browser.close();
});
  • Page会触发多种事件(下面描述的),可以用 node原生的方法 来捕获处理,比如 on,once 或者 removeListener。 下面的例子捕获了一个 page 实例的 load 事件,打印了一句话:
page.once('load', () => console.log('Page loaded!'));
  • 可以用 removeListener 取消对事件的监听:
function logRequest(interceptedRequest) {
    console.log('A request was made:', interceptedRequest.url());
}
page.on('request', logRequest); // 一段时间后...page.removeListener('request', logRequest);

Methods

page.$(selector)v0.9.0

  • selector <string> 选择器 返回: <Promise<?ElementHandle>>

  • 此方法在页面内执行 document.querySelector。如果没有元素匹配指定选择器,返回值是 null。

  • page.mainFrame().$(selector) 的简写。

page.$$(selector)v0.9.0

  • selector <string> 选择器

  • 返回: <Promise<Array<ElementHandle>>>

  • 此方法在页面内执行 document.querySelectorAll。如果没有元素匹配指定选择器,返回值是 []。

  • page.mainFrame().$$(selector) 的简写。

page.waitForSelector(".index-content .click-zoom a")

  • 等待页面元素加载完成
await page.waitForSelector(".index-content .click-zoom a")

page.waitFor(1000)

  • 等待1000毫秒执行
await page.waitFor(1000)

page.click('.btn')

await page.click('.btn')
  • 点击class 为btn元素

page.evaluate

  • 执行原生js
await page.evaluate(() => {
      document.getElementById("HD_CheckIn").value = "2020-07-11";
})

示例

  • 代码执行
  • 安装 puppeteer 依赖包
  • node xxx.js 运行js
/**
* 爬取游戏站数据 https://game.pipajam.com/
*/
const fs = require('fs')
const puppeteer = require('puppeteer');
(async () => {
    const browser = await puppeteer.launch({
        headless: false,
        args: ['--start-maximized', '--disable-infobars'],
        width: 1600,
        height: 900
    });
    // 1、 创建两个页面
    const page = await browser.newPage();
    const page2 = await browser.newPage();
    // 2、进入首页
    await page.goto(
        'https://game.pipajam.com/'
    );
    // 3、等待页面游戏数据元素加载完成
    await page.waitForSelector(".index-content .click-zoom a")
    // 4、获取所以游戏链接 游戏名称 
    const list = await page.$$eval(".index-content .click-zoom a", (el => el.map(el => ([el.href, el.getElementsByTagName('h6')[0].innerText]))));
    console.log(list);
    let len = list.length, index = 0, data = []
    // 5、调用函数 组装数据
    mainFun()
    async function mainFun () {
        try {
            // 6、开启page2 页面 获取游戏详情数据
            await page2.goto(
                list[index][0],{
                    timeout: 0
                }
            );
            // 7、等待详情卡片加载完成
            await page2.waitForSelector(".play-game-card .play-game-card-center")
            // 8、获取游戏链接地址 图片地址
            const item = await page2.$eval(".play-game-card .play-game-card-center", (el => [el.getElementsByTagName('p')[0].innerHTML, el.getElementsByTagName('img')[0].src]));
            await page2.click('.play-game-card .play-game-card-center a')
            const url = await page2.evaluate(param => window.location.href, "参数");
            // 9、组装数据
            data.push({
                description: item[0],
                img: item[1],
                instructton: "",
                keyfeatures: "",
                name: list[index][1],
                published: "Mon Oct 08 2018",
                tags: [],
                url,
                type: 'Children\'s intelligence',
            })
            console.log('以写入第'   (index 1)   '数据。');
            // 10、获取所以游戏数据 并写入指定json 文件
              index < len ? mainFun() : fs.writeFile('../../json/Game/pipajam.json', JSON.stringify(data), () => {})
        } catch (error) {
            console.log(error, 'err')
        }
    }
})();

到此这篇关于Node爬虫工具Puppeteer入门教程实践的文章就介绍到这了,更多相关Node Puppeteer入门内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Node爬虫工具Puppeteer入门教程实践的更多相关文章

  1. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. ios – 使用带有NodeJs HTTPS的certificates.cer

    我为IOS推送通知生成了一个.cer文件,我希望将它与NodeJSHTTPS模块一起使用.我发现HTTPS模块的唯一例子是使用.pem和.sfx文件,而不是.cer:有解决方案吗解决方法.cer文件可以使用两种不同的格式进行编码:PEM和DER.如果您的文件使用PEM格式编码,您可以像使用任何其他.pem文件一样使用它(有关详细信息,请参见Node.jsdocumentation):如果您的文件使

  3. 如何在XCode IDE中构建NodeJS?

    如何在XCodeIDE中将NodeJS构建为项目?NodeJS构建指令说它应该用以下内容构建:但是我希望在XCodeIDE中构建.我真正想要做的是在我的应用程序中嵌入NodeJS,所以我想如果我可以在XCode中构建NodeJS,那么我可以调整它以在我建立和运行NodeJS后添加我的应用程序.我想通过让V8在XCode中编译来取得一些进展,现在我正在尝试将NodeJS添加到V8项目中.解决方法在节点存储库根目录中运行./configure–xcode,您将获得所需的node.xcodeproj文件.

  4. 深入云存储系统Swift核心组件:Ring实现原理剖析

    它的目的是用于托管Rackspace的CloudFilesservice,原始项目代号是swift,所以沿用至今。Ring是Swift中最重要的组件,用于记录存储对象与物理位置间映射关系。先来看一下Swift文档中关于Ring的描述:Ring用来确定数据驻留在集群中的位置。有单独对应于Account数据库、container数据库和单个object的ring。Ring使用zone的概念来保证数据的隔离。每个partition的replica都确保放在了不同的zone中。本文逐步深入探讨了Swift如何通过

  5. Swift开发:创建XML文件,包含节点,属性值

    .append;//3创建第二个节点数据letitem2:Item=Item;for{letnode=Node;node.id=i+1;node.attributes=["ID":"\","Name":"N-\","disp":"1","Appliance":"1","Icon":"ic_switch_4"]item2.addNode;}xml.items?

  6. 泛型 – 符合Swift中Comparable的泛型类

    我正在尝试创建一个符合Comparable协议的简单通用节点类,以便我可以轻松地比较节点而无需访问其密钥.当我试图写

  7. swift3 – 将SceneKit对象放在SCNCamera当前方向的前面

    >生成SCNVector4,它定向节点,使其“面向”相机?但是让我有点失落.我看到了许多类似的问题,比如thisone,但没有答案.嘿,如果要将对象放在相对于另一个节点的某个位置,并且与参考节点的方向相同,则可以使用这个更简单的函数:如果您想将’node’2m放在某个’cameraNode’前面,你可以这样称呼:

  8. 如何在Swift中继承NSOperation以将SKAction对象排队以进行串行执行?

    Rob为子类化NSOperation提供了agreatObjective-Csolution,以实现SKAction对象的串行排队机制.我在自己的Swift项目中成功实现了这一点.要使用Actionoperation,请在客户端类中实例化NSOperationQueue类成员:在init方法中添加以下重要行:然后当您准备好向其添加SKActions时,它们会连续运行:您是否需要在任何时候终止操作:希望有所帮助!

  9. 核心数据 – 如何在Swift中定义CoreData关系?

    在CoreData中,我已经从Node到Tag定义了一个无序的多对多关系.我创建了一个这样的Swift实体:现在我想添加一个Tag到Node的一个实例,像这样:但是,这会失败,并显示以下错误:Terminatingappduetouncaughtexception‘NSinvalidargumentexception’,reason:‘Unacceptabletypeofvalueforto-ma

  10. 将“nil”值赋给Swift中的一般类型变量

    您需要将变量声明为可选项:不幸的是,这似乎触发了一个未实现的编译器功能:您可以通过使用NSObject的类型约束声明T来解决它:

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部