爬虫 puppeteer

github

安装

npm i puppeteer --registry=https://registry.npm.taobao.org
# 不下载驱动
npm i puppeteer-core --registry=https://registry.npm.taobao.org

手动查看下载地址

在 node_modules 目录下

// node_modulespuppeteerlibBrowserFetcher.js
chrome: {
        linux: '%s/chromium-browser-snapshots/Linux_x64/%d/%s.zip',
        mac: '%s/chromium-browser-snapshots/Mac/%d/%s.zip',
        win32: '%s/chromium-browser-snapshots/Win/%d/%s.zip',
        win64: '%s/chromium-browser-snapshots/Win_x64/%d/%s.zip',
}

chrome: {
        host: 'https://storage.googleapis.com',
        destination: '.local-chromium',
}

function archiveName(product, platform, revision) {
    if (product === 'chrome') {
        if (platform === 'linux')
            return 'chrome-linux';
        if (platform === 'mac')
            return 'chrome-mac';
        if (platform === 'win32' || platform === 'win64') {
            // Windows archive name changed at r591479.
            // 注意这一段 在自己拼接字符串时,当版本号 > 591479 则使用 chrome-win 否则使用 chrome-win32
            return parseInt(revision, 10) > 591479 ? 'chrome-win' : 'chrome-win32';
        }
    }
    else if (product === 'firefox') {
        return platform;
    }
}

// node_modulespuppeteerpackage.json
"puppeteer": {
    "chromium_revision": "737027",
    "firefox_revision": "latest"
  }
// 将上面的信息组合后
https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/737027/chrome-win.zip

在Linux中使用 pyppeteer 可能会出现超时错误

pyppeteer 0.2.2 不会出现这样的问题

将 connection.py 这个文件的内容修改就好了。

        self._ws = websockets.client.connect(
            # self._url, max_size=None, loop=self._loop)
            self._url, max_size=None, loop=self._loop, ping_interval=None, ping_timeout=None)

常用操作

  • 输入字符
await page.type("#name", "iFan")
  • 点击节点
await page.click('#btn-submit');
  • 获取属性
const searchValue = await page.$eval('#search', el => el.value);
const preloadHref = await page.$eval('link[rel=preload]', el => el.href);
const text = await page.$eval('.text', el => el.textContent);
const html = await page.$eval('.main-container', e => e.outerHTML);
const text = await page.$eval('.main-container', el => el.innerText);
// page.$(selector) 与我们常用的 document.querySelector(selector) 一致,返回的是一个 ElementHandle 元素句柄
// page.$$(selector) 与我们常用的 document.querySelectorAll(selector) 一致,返回的是一个数组
  • 获取属性集合
const textArray = await page.$$eval('.text', els => Array.from(els).map(el=> el.textContent));
  • 等待页面加载完成
await page.waitForNavigation({ waitUntil: "networkidle" })
  • 获取cookie,转为string格式
const cookies = await page.cookies()
const cookiesStr = cookies.map(cookie => `${cookie.name}=${cookie.value}`).join(";");
  • 等待一哈
page.waitFor(1000)
  • 滑动到页面底端
async function autoScroll(page){
    await page.evaluate(async () => {
        await new Promise((resolve, reject) => {
            var totalHeight = 0;
            var distance = 100;
            var timer = setInterval(() => {
                var scrollHeight = document.body.scrollHeight;
                window.scrollBy(0, distance);
                totalHeight += distance;

                if(totalHeight >= scrollHeight){
                    clearInterval(timer);
                    resolve();
                }
            }, 100);
        });
    });
}

常用参数

参数 用途
--disable-web-security 禁用同源策略(允许跨域)
--proxy-server=127.0.0.1:1080 设置代理
--proxy-server='direct://' 禁用代理
--proxy-bypass-list=* 不走代理的链接
--no-sandbox 禁用沙箱
--disable-gpu 禁用GUP
--ignore-certificate-errors 忽略证书错误
--auto-open-devtools-for-tabs 自动打开调试工具
--remote-debugging-port=9222 开启远程调试
--disable-translate 禁用翻译提示
--disable-background-timer-throttling 禁用后台标签性能限制
--disable-site-isolation-trials 禁用网站隔离
--disable-renderer-backgrounding 禁止降低后台网页进程的渲染优先级
--headless 无头模式启动
--user-data-dir=./karma-chrome 设置用户资料的储存位置
window-size=1920,1080 窗口尺寸,相当于设置window.outerWidth/outerHeight 注: chromium的窗口分辨率存在限制,在非无头模式下,不能大于浏览器实际分辨率
--enable-automation 使得JS检查无头浏览器无效
executablePath 设置自己下载的浏览器的位置

Page

Page 是 Puppeteer 中最重要的一个 API,也是它的核心所在,这里会介绍一些常用的 Page API。

设置页面环境

方法名 描述
page.emulate 设置 viewport 和 ua
page.setViewport 设置 viewport
page.setUserAgent 设置 ua
page.setRequestInterception 中断所有请求,并可以修改请求的返回值
page.addScriptTag 添加 js 脚本
page.addStyleTag 添加 css
page.setContent 设置整个 html
page.setCacheEnabled 设置缓存是否开启
page.setExtraHTTPHeaders 设置额外的 http 头
page.setGeolocation 设置地理位置
page.setJavaScriptEnabled 设置 js 是否开启
page.setOfflineMode 设置离线模式
page.deleteCookie 删除 cookies
page.setCookie 设置 cookies

模拟动作

一般会先滚动视窗到相应元素那,再执行动作。

方法名 描述
page.click 点击
page.tap 手指点击
page.focus 聚焦
page.hover hover
page.type 在指定元素中输入内容
page.select 选中 `` 的某个选项

等待

方法名 描述
page.waitFor 等待某个元素渲染出来,或者某个函数执行之后返回 true,或者直接等待指定的时间
page.waitForSelector 等待某个元素被渲染
page.waitForFunction 等待某个函数执行之后返回 true
page.waitForNavigation 等待页面跳转
page.waitForRequest 等待某个特定的请求被发出
page.waitForResponse 等待某个特定的请求收到了回应

执行脚本

方法名 描述
page.$ 使用 document.querySelector 获取结果,会返回 ElementHandle,可以传递使用
page.$$ 同上,不过使用的是 document.querySelectorAll
page.$eval document.querySelector 获取的结果传递给 pageFunction
page.$$eval 同上,不过使用的是 document.querySelectorAll
page.evaluate 直接执行脚本
page.evaluateHandle 执行脚本,返回的是 JSHandle,可以传递使用
page.evaluateOnNewDocument 在下个 frame 执行脚本
page.exposeFunction 将函数注入到 window 对象上
page.queryObjects 获取所有属于这个类的对象,可以传递使用

页面跳转

方法名 描述
page.goto 跳转页面
page.close 关闭
page.goBack 后退
page.goForward 前进
page.reload 刷新
page.setDefaultNavigationTimeout 设置页面跳转的超时时长

获取内容

方法名 描述
page.screenshot 截屏
page.pdf 生成 pdf
page.content 获取整个页面内容
page.title 获取页面 title
page.url 获取页面 url
page.viewport 获取页面 viewport
page.cookies 获取 cookies

事件

事件名 描述
page.on('console') 监听 console.log 等的调用
page.on('dialog') 监听页面的 alert, beforeunload, confirmprompt 弹窗
page.on('load') 监听页面的加载
page.on('domcontentloaded') 监听页面 dom 加载完成
page.on('pageerror') 监听页面错误
page.on('request') 监听页面发送的请求
page.on('requestfailed') 监听失败的请求
page.on('requestfinished') 监听完成的请求
page.on('response') 监听页面接受到的响应

命名空间

通过一些命名空间可以快速访问到该页面下的其他实例。

属性名 描述
page.keyboard 访问到页面的 Keyboard 对象
page.mouse 访问到页面的 Mouse 对象
page.touchscreen 访问到页面的 TouchScreen 对象
原文地址:https://www.cnblogs.com/iFanLiwei/p/12824796.html