Puppeteer使用总结

32 篇文章 0 订阅

文章目录

NodeJS环境配置

Nodejs下载地址:http://nodejs.cn/download/

image-20210310154607346

MAC配置

从官网下载并直接安装就可以了

安装方式二:
# 查看node版本
brew search node

# 安装node
brew install node

# 检查是否安装成功
node -v
npm -v
node版本管理:
npm install -g n

# 查看所有node版本
n ls

# 从安装的node中切换不同版本
n

# 安装node 12版本
n 12

Linux配置

sudo apt-get install nodejs

同样可以采用node版本管理工具n进行版本切换

Windows配置

  1. 下载好安装包

  2. 全部默认-下一步-Finish完成安装(可以改个安装路径,我一般装到D盘)

  3. CMD打开命令行,输入node -vnpm -v查看node、npm的版本号

  4. 配置全局模块安装路径和缓存路径,在nodejs的安装目录下创建两个文件夹node_globalnode_cache

  5. CMD打开命令行,执行下面内容(具体路径根据你自己的填写)

    npm config set perfix "D:Program Files
    odejs
    ode_global"
    npm config set cache  "D:Program Files
    odejs
    ode_cache"
    
  6. 系统环境变量新建NODE_PATH,路径是上面添加的node_global文件夹下新建的node_modules文件夹

    D:Program Files
    odejs
    ode_global
    ode_modules
    
  7. 编辑用户变量path,添加一个node_global路径

    D:Program Files
    odejs
    ode_global
    

Windows配置环境参考地址:https://www.cnblogs.com/hshdexy/p/13605176.html

开发环境初始化

基础环境

  1. 找个位置新建一个文件夹,例如:test

  2. 创建一个js文件,例如test.js

  3. 进入test文件夹,在该目录下运行命令行,并执行下面命令

    npm init
    # 之后就一路回车就行了,就是填写一个项目描述之类的,之后会生成一个package.json的配置文件
    
  4. 因为要在工程中使用puppeteer,运行如下命令进行安装(参考GitHub)

    npm i puppeteer
    # or "yarn add puppeteer"
    

    提示:安装Puppeteer时,它会下载最新版本并且可以与Puppeteer一起使用的Chromium(Mac170MB ,Linux282MB ,Windows280MB )(翻译自Github)

    这里我在Mac上进行开发的,就直接使用这个了,因为我需要在浏览器上显示程序的运行过程,后面部署到Linux服务器上的时候就不再使用浏览器了(可以自定义浏览器类型),就可以安装puppeteer-core,安装步骤如下

    npm i puppeteer-core
    # or "yarn add puppeteer-core"
    

    提示:从1.7.0版开始,官方发布了puppeteer-core软件包,这是一个Puppeteer版本,默认情况下不会下载任何浏览器。puppeteer-core旨在作为Puppeteer的轻量级版本,用于启动现有的浏览器安装或用于连接到远程浏览器。确保您安装的puppeteer-core版本与您打算连接的浏览器兼容。(翻译自Github)

  5. 官方截图例子

    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto('https://example.com');
      await page.screenshot({ path: 'example.png' });
    
      await browser.close();
    })();
    
  6. 编辑完test.js保存,然后在命令行中运行如下命令执行该脚本

    node test.js
    

GitHub地址: https://github.com/puppeteer/puppeteer

百度OCR对接

说明:因为我自己的程序中需要用验证码识别,所以使用了百度的OCR

下载文字识别Node.js SDK: https://ai.baidu.com/sdk#ocr

  1. 将SDK单独解压到一个文件夹内,例如aip-node-sdk-version,并复制到test文件夹下

  2. 进入到aip-node-sdk-version文件夹内运行如下命令,安装sdk依赖库

    npm install
    
  3. 把目录当做模块依赖

  4. 进入到test文件夹下安装依赖

    npm install baidu-aip-sdk
    
  5. 可以使用百度普通文字识别的示例接口

    var fs = require('fs');
    
    var image = fs.readFileSync("assets/example.jpg").toString("base64");
    
    // 调用通用文字识别, 图片参数为本地图片
    client.generalBasic(image).then(function(result) {
        console.log(JSON.stringify(result));
    }).catch(function(err) {
        // 如果发生网络错误
        console.log(err);
    });
    
    // 如果有可选参数
    var options = {};
    options["language_type"] = "CHN_ENG";
    options["detect_direction"] = "true";
    options["detect_language"] = "true";
    options["probability"] = "true";
    
    // 带参数调用通用文字识别, 图片参数为本地图片
    client.generalBasic(image, options).then(function(result) {
        console.log(JSON.stringify(result));
    }).catch(function(err) {
        // 如果发生网络错误
        console.log(err);
    });;
    
    var url = "https//www.x.com/sample.jpg";
    
    // 调用通用文字识别, 图片参数为远程url图片
    client.generalBasicUrl(url).then(function(result) {
        console.log(JSON.stringify(result));
    }).catch(function(err) {
        // 如果发生网络错误
        console.log(err);
    });
    
    // 如果有可选参数
    var options = {};
    options["language_type"] = "CHN_ENG";
    options["detect_direction"] = "true";
    options["detect_language"] = "true";
    options["probability"] = "true";
    
    // 带参数调用通用文字识别, 图片参数为远程url图片
    client.generalBasicUrl(url, options).then(function(result) {
        console.log(JSON.stringify(result));
    }).catch(function(err) {
        // 如果发生网络错误
        console.log(err);
    });;
    

我的实例代码

const puppeteer = require('puppeteer');

// 网站用户名和登陆密码
const userName = "xxxxxxxxxx";
const passWord = "xxxxxxxxxx";
// 网站首页和职位列表地址
const gotoUrl = "xxxxxxxxxxxx";
const listUrl = "xxxxxxxxxxxx";
// 验证码图片路径
const verCodeImgPath = "verCodeImg.png";
// 验证码
let code;
// 引用百度OCR
let AipOcrClient = require('baidu-aip-sdk').ocr;

// 设置百度OCR APPID/AK/SK
let APP_ID = "xxxxx";
let API_KEY = "xxxxxxxxx";
let SECRET_KEY = "xxxxxxxxx";

// 新建一个对象,建议只保存一个对象调用服务接口
let client = new AipOcrClient(APP_ID, API_KEY, SECRET_KEY);
// 本地图片上传
let fs = require('fs');

// 刷新函数
async function refresh() {
  const browser = await puppeteer.launch({
    // 无头模式,不打开浏览器显示脚本运行过程,可以在调试过程中打开
    headless: true,
    // 设置浏览器窗口大小
    defaultViewport: {
      width: 1000,
      height: 2000,
    }
  });
  const page = await browser.newPage();
  try {
    // 进入登陆页面,并等待直到没有网络连接的时候向下进行
    await page.goto(gotoUrl, {
      waitUntil: "networkidle2",
    });
  } catch(e) {
    console.log("登陆页面无法访问!");
    // 关闭浏览器并返回不再向下运行,本次刷新失败
    await browser.close();
    return;
  }
  
  // 填写用户名
  try {
    // 找到用户名的标签元素
    let accountElements = await page.$x('//input[@id="UserName"]', {
      waitForTimeout: 3000
    });
    // 填写用户名
    await accountElements[0].type(userName)
  } catch (e) {
    console.log("用户名输入失败!");
    await browser.close();
    return;
  }
  await page.waitForTimeout(2000);
  // 填写密码
  try {
    // 找到密码的标签元素
    let pwdElements = await page.$x('//input[@id="UserPass"]', {
      waitForTimeout: 3000
    });
    // 填写密码
    await pwdElements[0].type(passWord)
  } catch (e) {
    console.log("密码输入失败!");
    await browser.close();
    return;
  }

  // 选择用户类型
  await page.click('#RadioC');
  // 提交表单
  await page.click('#Denglu');
  // 等待5秒加载页面
  await page.waitForTimeout(5000);

  // 跳转到职位列表页面
  try {
    // 等待直到没有网络连接的时候向下进行
    await page.goto(listUrl, {
      waitUntil: "networkidle2"
    });
  } catch (e) {
    console.log("职位列表页面无法访问!");
    await browser.close();
    return;
  }

  //点击全选
  try {
    await page.click("#CheckAll");
  } catch (e) {
    console.log("全选失败!");
    await browser.close();
    return;
  }

  // 找到验证码标签元素
  const verCodeImg = await page.$('body > div:nth-child(5) > table > tbody > tr > td:nth-child(3) > form > table:nth-child(5) > tbody > tr > td:nth-child(2) > img');
  // 判断验证码标签是否存在
  if (verCodeImg) {
    // 获取到验证码并存储到本地
    try {
      await verCodeImg.screenshot({
        path: verCodeImgPath
      });
      var image = fs.readFileSync(verCodeImgPath).toString("base64");
    } catch (e) {
      console.log("验证码截取错误!");
      await browser.close();
      return;
    }
    // 百度OCR
    // 调用通用文字识别, 图片参数为本地图片
    client.generalBasic(image).then(async function(result) {
      code = result.words_result[0].words;
      // 等待识别结果
      await page.waitForTimeout(3000);
    }).catch(async function(err) {
      // 如果发生网络错误
      console.log(err);
      console.log("百度OCR接口发生网络错误!");
      await browser.close();
      return;
    });
    // 填写验证码
    try {
      // 直到验证码输入框标签元素
      let codeInput = await page.$("#Tel");
      // 等待2秒
      await page.waitForTimeout(2000);
      // 输入验证码
      await codeInput.type(code);
      // 等待2秒
      await page.waitForTimeout(2000);
    } catch (e) {
      console.log("验证码输入错误!");
      await browser.close();
      return;
    }
  }

  //点击刷新职位
  try {
    // 点击刷新职位按钮
    await page.click("#btn_tigao");
    // 等待3秒,实际测试的时候这里有个响应时间,所以必须有等待时间
    await page.waitForTimeout(3000);
    console.log("刷新成功!");
  } catch (e) {
    console.log("刷新失败!");
    await browser.close();
    return;
  }
  await browser.close();
}
// 运行一次刷新函数
refresh();
// 设置一个2分钟刷新一次
setInterval(() => {
  refresh();
}, 120 * 1000);

Docker部署

待补充

小知识点

  • 不会用xpath选择器选择标签怎么办?

    image-20210310172116052

    直接在定位到标签处-右击-复制-复制选择器,粘贴到page.$x('')单引号中即可,很简单!

  • 对某个标签进行截图,先获取到标签元素,然后使用element.screenshot即可

Puppeteer 语法

待补充

函数

说明

waitForTimeout

等待n毫秒后下下执行,类似于以前的waitFor

page.screenshot

页面截图

element.screenshot

获取到了标签元素也可以截图

错误总结

  1. 树莓派(Ubuntu)运行错误:
  • Error: Failed to launch the browser process puppeteer

  • 解决方法:

    sudo apt-get install chromium-browser

  1. 树莓派(Ubuntu)运行使用puppeteer-core:
  • 需要安装puppeteer-core

  • js文件中引用puppeteer-core

    const puppeteer = require('puppeteer-core');
    
  1. async修饰的函数中,每个操作都要添加上await

我的博客

博客会更新的比较及时,有问题请留言!

博客地址:https://pixiao.gitee.io/blog

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Puppeteer 中可以使用 `page.click()` 方法来点击元素,在调用该方法后可以使用 `page.waitForNavigation()` 方法来判断点击是否成功。该方法会等待页面完成跳转,并返回一个 promise 对象,可以使用 `.then()` 方法来获取跳转后的页面信息。 代码示例: ``` await page.click('#myButton'); await page.waitForNavigation().then(() => { console.log('点击成功'); }); ``` 如果需要等待页面中某个元素出现或消失时使用 `page.waitForSelector()` and `page.waitForSelector()` ``` await page.click('#myButton'); await page.waitForSelector('#success-message', {visible: true}) console.log('点击成功'); ``` 这里有一些其他等待页面变化的方法,可以根据实际情况选择使用 - `page.waitForNavigation()` - `page.waitForResponse()` - `page.waitForRequest()` - `page.waitForFunction()` ### 回答2: Puppeteer 是一个通过控制和操作浏览器来进行自动化测试和爬取数据的工具,它可以模拟用户操作浏览器并截取网页内容。当使用 Puppeteer 进行点击操作时,我们可以使用下面的方法来判断点击元素是否成功: 1. 使用 page.waitForNavigation() 方法等待页面跳转。在点击元素后,如果页面会发生跳转,我们可以通过该方法等待页面完成跳转,这样就可以判断点击是否成功。例如: ``` await Promise.all([ page.waitForNavigation({ waitUntil: 'networkidle0' }), // 等待页面跳转完成 page.click('selector') // 点击元素 ]); ``` 2. 使用 page.waitForSelector() 方法等待元素出现。通过等待元素在 DOM 中出现,我们可以判断点击事件是否成功。例如: ``` await Promise.all([ page.waitForSelector('selector'), // 等待元素出现 page.click('selector') // 点击元素 ]); ``` 3. 使用 page.evaluate() 方法判断点击后的页面变化。使用该方法可以在当前页面中执行 JavaScript 代码,我们可以通过执行一段代码来判断点击事件是否成功。例如: ``` await page.evaluate(() => { const element = document.querySelector('selector'); // 查找元素 if (element === null) { throw new Error('Element not found'); // 如果元素未找到,抛出错误 } element.click(); // 点击元素 }); ``` 通过以上方法,我们可以在 Puppeteer 中判断点击元素是否成功。根据需要可以使用其中的一种或多种方法来进行验证。 ### 回答3: Puppeteer 是一个用于控制 Chrome 或 Chromium 浏览器的 Node.js 库,提供了对页面的操作和控制能力。 在 Puppeteer 中,要判断点击元素是否成功,可以通过以下步骤: 1. 使用 `page.click()` 方法模拟点击操作。该方法接受一个字符串选择器作为参数,表示要点击的元素。如`await page.click('#myButton')`。 2. 等待点击操作完成。在 Puppeteer 中,可以使用 `page.waitForNavigation()` 方法等待页面导航完成,或者使用 `page.waitForSelector()` 方法等待页面中的某个元素加载完成。例如,`await page.waitForNavigation()` 或者 `await page.waitForSelector('#myElement')`。 3. 判断点击是否成功。在点击操作完成后,可以进一步验证页面是否发生了预期的变化。可以使用 `page.$eval()` 方法或其他相应的页面方法来获取某个元素的属性或内容,并与预期的结果进行比较。如`const elementText = await page.$eval('#myElement', el => el.innerText);` 总结来说,要判断点击元素是否成功,可以模拟点击操作,并等待页面的导航或元素加载完成。然后,通过验证相应的元素属性或内容,来判断点击操作是否生效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值