手记

nodejs:stream+puppteer 入门级爬虫

1 puppeteer 是一个node包,可以实现 在nodejs运行环境中模拟用户通过客户端访问网站,进行鼠标键盘等UI行为,以及更加丰富的客户端浏览器接口
4. 案例中没有使用真实的网址以及选择器,使用爬虫前最好了解下相关法律法规,爬虫技术有一定成瘾性,慎重入坑。

const puppeteer = require("puppeteer");
const fs = require("fs");
const path = require("path");

const puppteerInstanc = async () => {
  const browser = await puppeteer.launch({
    args: ["--no-sandbox"],
    dumpio: false,
    headless: false
  });
  const page = await browser.newPage();

  //打开网站 第二个参数表示数据请求结束
  await page.goto(
    "https://********.com",
    { waitUntil: "networkidle2" }
  );
  //如果是要截图的话需要关闭一些蒙版提示,cookie设置太麻烦,而且无法绕过客户端本地的路由拦截器,模拟鼠标移动和点击很多时候还是很有必要的。
  try {
    const btn = await page.$(
      "********"
    );
    await btn.click();
  } catch (error) {}

  //选择15K-25K   点击按钮  找到元素之后右键 copy=> copySelect, 可以吧当前元素选择器粘贴出来
  const salary15 = await page.$(
    "********"
  );
  await salary15.click();
  await page.waitFor(1000);

  //创建数据容器 这里用到stream文件流,数据量还是很大的。应该还有优化提升空间
  const file1 = path.resolve(__dirname, "data.txt");
  const writerStream = fs.createWriteStream(file1, {
    flags: "r+",
    encoding: "utf-8"
  });

  //遍历某dom容器  page.$eval的第二个参数是DOM对象,去获取子元素的内容,拼接为对象
  for (var i = 1; i < 91; i++) {
    const ele = await page.$eval(`#list`, ele => {
      return {
        name: ele.querySelector(
          ".list_title"
        ).innerText,
        company: ele.querySelector(
          ".list_company"
        ).innerText,
        salary: ele.querySelector(
          ".list_saray"
        ).innerText
      };
    });
    var data = JSON.stringify(ele);
    writerStream.write(data, "UTF8");
  }
  
  // 下一页
  var pageCount = 1;
  async function getDomValue() {
  //由于下一页的点击按钮不稳定,所以使用路由跳转方式。
    // const nextBtn = await page.$$(".btn",ele=>ele[1]);
    // await nextBtn.click();
    // await page.waitFor(1000);
    await page.goto(
      "https://*****.com/?page=${pageCount}&a=1,b=1,c=1",
      { waitUntil: "networkidle2" }
    );
    pageCount++;
    try {
      await page.waitForSelector(`#list`);
    } catch (error) {
      console.log(`第${pageCount}页暂时没有数据.........`);
      // 标记文件末尾
      writerStream.end();
    }

    for (var i = 1; i < 91; i++) {
      const ele = await page.$eval(
        `#list > div:nth-child(${i})`,
        ele => {
          return {
            name: ele.querySelector(
              ".el__title"
            ).innerText,
            company: ele.querySelector(
              ".company"
            ).innerText,
            salary: ele.querySelector(
              ".salary"
            ).innerText
          };
        }
      );
      var data = JSON.stringify(ele);
      writerStream.write(data, "UTF8");
    }
    console.log(`抓取第${pageCount}页成功。。。`);
    getDomValue();
  }
  await getDomValue();
};
puppteerInstanc();
0人推荐
随时随地看视频
慕课网APP