使用nodejs和python脚本实现爬虫程序,并将抓取数据生成词云图看板

发布于:2024-04-30 ⋅ 阅读:(125) ⋅ 点赞:(0)
  1. 创建项目,初始化目录结构。
  • 创建项目名称为pachong。
  • 运行 npm init -y 初始化项目。
  • 修改package.json文件中的type属性为module。
  • 安装 npm 包:npm install puppeteer #爬虫 | 自动化UI测试
  • 首先确保你的电脑上有python3环境
  • 安装两个python包 pip install wordcloud #生成词云图 pip install jieba #中文分词 (⚠️注意:如果安装的是python3,你的python包管理工具是pip3而不再是pip)

在这里插入图片描述

  1. 创建src目录。
  • 新建两个文件分别用于书写nodeJs代码和python代码。
  • 在网上找一个自己喜欢的字体ttf文件,准备让生成的词图云使用。
    在这里插入图片描述
  1. 介绍我们要爬取的内容
  • 我们要爬取的是掘金首页的导航栏 -> 前端模块 -> 推荐
  • 爬取前端(或者其他指定模块)推荐模块里所有文章的标题,并且依靠python脚本提供的分词和词图云的能力最终生成看板。
    在这里插入图片描述
  1. source code

index.js

import puppeteer from "puppeteer"; // puppeteer 的每一个操作都是异步的
import { spawn } from "node:child_process";
const keywords = process.argv[2]; // 获取在终端执行 node index.js keywords 中的 keywords

// 1. 创建一个浏览器实例
const browser = await puppeteer.launch({
  headless: false, // 关闭无头模式 (什么是无头模式:无需打开浏览器就可以直接爬取,我们做demo还是想看到效果因此暂时关掉)
});

// 2. 创建一个页面实例
const page = await browser.newPage();

// 3. 跳转页面
await page.goto("https://juejin.cn");

// 4. 确保页面挂载完毕再进行爬取操作
await page.waitForSelector(".side-navigator-wrap"); // 存放导航栏的父容器
// 5. 获取导航项元素例如:前端、后端、IOS等等 page.$表示获取单个元素, page.$$表示获取多个元素。
const elements = await page.$$(".side-navigator-wrap .nav-item-wrap span");

// utils function
const collectFunc = async () => {
  const titleList = [];
  // 等待内容加载完毕
  await page.waitForSelector(".entry-list");
  // 获取推荐模块的标题
  const elements = await page.$$(".entry-list .content-main .title-row");
  for await (const el of elements) {
    const prop = await el.getProperty("innerText");
    let text = (await prop.jsonValue()).trim();
    titleList.push(text);
  }

  const pyProcess = spawn("python3", ["./index.py", titleList.join(",")]);
  pyProcess.stdout.on("data", (chunk) => {
    console.log("chunk:", chunk.toString());
  });

  pyProcess.stderr.on("error", (err) => {
    console.error("error:", err);
  });

  pyProcess.on("close", (code) => {
    console.log(`child process exited with code ${code}`);
  });
};

// 6. 读取各个导航项
for await (const el of elements) {
  const prop = await el.getProperty("innerText");
  let text = (await prop.jsonValue()).trim();

  // 执行node index.js keywords命令时,keywords要是不传那就默认点击前端,否则点击keywords
  if (text === (keywords || "前端")) {
    await el.evaluate((b) => b.click());
    await collectFunc();
    break;
  }
}

index.python

import jieba #引入结巴库
from wordcloud import WordCloud #引入词云图
import matplotlib.pyplot as plt
import sys
text = sys.argv[1]
words = jieba.cut(text) #中文分词
#添加字体文件 随便找一个字体文件就行 不然不支持中文
font = './font.ttf'
info = WordCloud(font_path=font,width=1000,height=800,background_color='white').generate(''.join(words))

#输出词云图
plt.imshow(info,interpolation='bilinear')
plt.axis('off')
plt.show()

  1. 展示效果
    在这里插入图片描述

网站公告

今日签到

点亮在社区的每一天
去签到