【从入门到放不下系列】记一次用 puppeteer 爬数据的历程(下)—— 爬取搜狗微信搜索的公众号文章

上回书说到,使用 puppeteer 库做了截图操作简单展示了 puppeteer 的特性和基本使用方法。这回我们来说说用 puppeteer 做爬取页面数据并写入 Excel 的操作。

puppeteer 实战:爬取搜狗微信搜索的公众号文章并写入 Excel

首先背景:搜狗搜索现在有个功能可以根据关键字来查询微信公众号文章,而我们要做的就是把指定关键字的文章给它爬下来,由于这个需求是从我司业务部门那边来的,所以为了方便运营同学查看,还需要把爬到的数据放到放到 Excel 中去。

使用完的感受是,这个东西只要读懂 API,其实并不复杂。个人觉得复杂的的地方在于需要考虑各种 base case。
首先第一个一般的网站都做了防爬处理,我们需要苦旅通过合理的方式绕过。比如搜狗搜索这个就是,刚开始我计划通过读取到 a 标签的 href 属性,然后直接在浏览器中打开这个链接。但尝试后发现,并能这样操作,估计是搜狗做了什么防爬操作,这样做会报 IP 异常。遂放弃,使用 puppeteer 的 page.click 方法解决了这个问题,因为实质上 puppeteer 是通过模拟真实用户的点击操作来实现的,所以并不会受防爬机制的影响。
另外一个就是因为爬取的是微信文章,所以还要考虑微信文章本身的一些情况,比如说文章被发布者删除或迁移、文章被举报,或者这篇文章时分享另外一篇文章等等情况…

总之,感觉用 puppeteer 写的爬虫脚本都是和业务强耦合的,所以个人觉得代码本身并没有什么参考意义。但是我再编写过程中遇到的各种奇葩问题还是可以看看,也许能为解决你遇到的问题提供一点思路。

完整代码如下:

const cheerio = require("cheerio");
const puppeteer = require("puppeteer");
const company = require("./company.json");
const keywords = require("./keywords.json");
const {
    exportExcel } = require("./export");

// 获取不通关键字搜索结果页面 url
function getUrl(queryWords, currPage = 1) {
   
  return `https://weixin.sogou.com/weixin?type=2&s_from=input&query=${
     queryWords}&page=${
     currPage}`;
}
(async function() {
   
  const width = 1024;
  const height = 1600;
  // 创建一个浏览器实例
  const browser = await puppeteer.launch({
   
    // 关闭 Chrome 无头(无界面)模式
    headless: false,
    // 顾名思义,设置默认视窗宽高
    defaultViewport: {
    width: width, height: height }
  });
  async function sougouSpiders(keywords) {
   
    // 新建一个页面(浏览器 Tab 页)
    const page = await browser.newPage();
    // 设置页面等待超时时间,可以稍微长一点,避免因网络原因导致抛错
    page.setDefaultNavigationTimeout(90000);
    // 设置新开 Tab 页的宽高
    await page.setViewport({
    width: width, height: height });
    let currSpiderPage = 1;
    // 在新开的 Tab 页中打开某一个关键字的 url
    await page.goto(getUrl(keywords, currSpiderPage), {
   
      withUntil: "networkidle2"
    });
    // 拿到页面内容
    let firstPageHtml = await page.content();
    // 获取 cheerio 实例
    let $ = await cheerio.load(firstPageHtml);
    const is404 = $(".main-left")
      .eq(0)
      .text()
      .includes("没有找到相关的微信公众号文章。");
    // 考虑可能会有关键字查询无果的情况
    if (is404) {
   
      console.log("当前关键字无检索结果!");
      // 如果关键字查询无果,则关闭这个页面
      await page.close();
    } else {
   
      // 根据分页组件的值读取到当前关键字的检索结果共有多少页
      const totalPage =
        Array.from($(".p-fy a")).length === 0
          ?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值