Node 实现爬虫 及 自动化测试

1,564 阅读2分钟

看名字高大上,其实很简单;

下面介绍下简版的 爬虫自动化测试; 详细的涉及到公司业务就不搬出来了;

一、技术介绍

  1. 通过 koa 搭建一个 node 服务
  2. cheerio 实现爬虫,这里以爬取亚马逊折扣商品链接为例
  3. puppeteer 实现自动化测试

二、原理

2.1 cheerio

  • Cheerio是一个用于解析HTML文档的库,它不需要执行JavaScript代码,在服务器端快速获取HTML页面的DOM结构。使用Cheerio可以方便地进行DOM操作、数据抓取和爬虫等任务;

  • 其实就是打开一个url界面, 然后通过获取节点的方式,获取到对应节点内容;在做解析;

2.2 puppeteer

  • puppeteer是一个Node.js库,用于控制Headless ChromeChromium浏览器(无头浏览器),可以进行自动化测试、屏幕截图、数据采集等任务。Puppeteer可以模拟用户的操作行为,例如点击、输入、滚动等等。

  • 通过打开一个无头浏览器,渲染界面,通过 puppeteer 拿到对应节点,并为节点赋值,在执行点击;

  • 对应的数据收集和处理,可在自己项目对应界面添加数据埋点;

三、代码片段

以下代码可执行粘贴复制运行,就能看到结果

3.1 cheerio

// 请求 url - > html(信息)  -> 解析html
const https = require('https');
const request = require('request')
const cheerio = require('cheerio');
const fs = require('fs');
// 请求 top250
// 浏览器输入一个 url, get
const urlPath = 'https://affiliate-program.amazon.com/home/promohub/promocodes/mpc'
const reg = /\/([a-zA-Z0-9\-]+)$/g
const getAmzData = async () => {
  const opt = {
    url: `${urlPath}category=`,
    method: 'get',
    headers: {'cookie': reqCookie }
  }
  
  request(opt, function(error, response, body) {
    const res = JSON.parse(body)
    const linksData = []
    const uCodeData = []
    const $ = cheerio.load(res.search_result);
    $('.search-result-item').each(function(){
      const link = $('.a-link-normal', this).attr('href');
      linksData.push(link)
      uCodeData.push(link.match(reg)[0])
    })
    // 将解析的文件写入
    const writeData = {
      linksData: linksData,
      uCodeData: uCodeData
    }
    const syData = JSON.stringify(writeData)
    fs.writeFile('./films.json', syData, function(err){
      if (!err) console.log('文件写入完毕');
    })
  })
}

getAmzData()

3.2 puppeteer

const puppeteer = require('puppeteer');

async function fun() {
  const browser = await puppeteer.launch({ headless: false, defaultViewport: { width: 1366, height: 768 } })
  const page = await browser.newPage()

  // 定位到目标页面
  await page.goto('https://www.amazon.com/ap/signin)

  // 打印页面所有的frame的地址
  await page.frames().map(frame => { console.log(frame.url()) })

  // 通过frame的url定位到frame
  const targetFrameUrl = 'https://www.amazon.com/ap/signin'
  const frame = await page.frames().find(frame => frame.url().includes(targetFrameUrl))

  // 获取账号 Node 节点 并赋值
  const phone = await frame.waitForSelector('#ap_email')
  await phone.type('wangyisong@updeals.com')

  // 获取密码框 Node 节点 并赋值
  const password = await frame.waitForSelector('#ap_password')
  await password.type('dianxiaomi2022')

  // 模拟点击登录按钮
  await page.click('#a-autoid-0-announce')

  // 结果以及调用信息可在自己的界面埋点输出

  // const oneCita = await page.waitForSelector('.promotions-list-table-body .search-result-item .a-link-normal')
  // const oneText = await page.$eval('div.fp-one-cita-wrapper > div.fp-one-cita > a', ele => ele.innerHTML)
  // console.log('oneCita: ', oneCita)
  const pages = await browser.pages()
  console.log(pages)
  const c_list = await pages[pages.length - 1].$$eval('.search-result-item .a-link-normal',e=>{
  console.log(c_list)

  await page.click('.promotions-list-table-body .search-result-item .a-link-normal')
}

fun()

四、结尾

纯属太久没更新博客了,凑凑数;