Nodejs 爬虫 第二章(通过掘金 userId 抓取到所有文章)!HTML to Markdown

news2025/1/11 22:41:23

前言

就在昨天晚上,做了一个通过掘金文章链接进行解析html转化为markdown文档,并且把图片进行下载和替换,但是最后也留了个伏笔(我一定会回来的~)就是通过用户id,把所有的文章都转化出来,今天实现了这个功能,已经更新仓库且来补充下文章。

拿到所有文章

怎么通过 userid 拿到所有文章呢,掘金肯定是有 API 的,通过翻页触发了一个接口/v1/article/query_list

a75c87f87d43325a4fbbddeca7fe4bd1.png

参数说明

请求参数

参数说明
cursor类似于offset,偏移量
sort_type排序方式,1热门,2最新
user_id掘金用户 ID

user_id 在掘金用户页的 URL 上获取即可。

68e9f82c04d67b7654a7a6df47e09e1f.png

返回参数

参数说明
data文章数据
cursor下次请求的 cursor
count文章总数
has_more是否还有更多文章
Array<{ article_id: int }>文章id
33cdab7321d817693d5f2b0c8a7edadc.png

本来是想着有个啥 limit 直接拉满 999999,但是发现没这参数。

但是在返回值里面发现了 has_more 代表是否还有更多文章。

24e0268bc55f826f268839fbf832b69a.png

开始遍历

既然不能一次性拿到所有文章,那就递归处理下,当发现还有更多文章时,先将文章的id都存起来,然后接着发请求,直到 has_morefalse,将前面的ids遍历进行转markdown

const postList = []

const handleGrabUserArticles = (requestOptions) => {
  request.post(requestOptions, (error, response) => {
    if(!error && response.statusCode === 200) {
      const { 
        data = [], 
        has_more, cursor 
      } = JSON.parse(body);
      
      // 数据存在则存入ids
      if(data?.length) {
        postList.push(...data?.map(article => article.article_id));
      }
      
      // 判断是否还有更多文章
      if(has_more) {
        configs.cursor = cursor;
        // 继续递归请求
        handleGrabUserArticles(getRequestOptions());
      } else {
        // 开始
        postList.forEach(id => handleGrabArticles(`https://juejin.cn/post/${id}`));
      }
    }
  })
}

运行一下看看效果

2469ddf0dc8b4046601d852a79f83ac7.png

可以看到文章全部拉取下来了,但是我觉得需要在代码里面修改太死板,于是乎,我决定加了个命令行交互。

继续优化

我的想法是让用户选择爬取方式,然后输入对应的ID开始爬取。

  1. 用户 ID

  2. 文章 ID

使用 inquirer 进行命令行交互

inquirer 在年初的终端GPT中使用过这个包,所以这次就不细说了。直接上代码。

const main = async () => {
  // 选择目标方式
  const { model: target } = await inquirer.prompt({
    type: 'list',
    name: 'model',
    message: '请选择爬取目标方式',
    choices: [
        { name: '通过用户 ID 爬取', value: 'user' },
        { name: '通过文章 ID 爬取', value: 'post' },
    ],
    // 默认选择用户
    default: configs.target
  })
  
  configs.target = target;
  // 如果选的是用户,就让用户输入 userid
  if(configs.target === 'user') {
    const { prompt: userId } = await inquirer.prompt({
      type: 'input',
      name: 'prompt',
      message: '请输入用户 ID',
    });
    configs.userId = userId?.trim();
    // 调用前面实现的获取用户所有文章方法
    handleGrabUserArticles(getRequestOptions())
    // 如果是文章则直接调用文章方法
  } else {
    const { prompt: postId } = await inquirer.prompt({
      type: 'input',
      name: 'prompt',
      message: '请输入文章 ID',
    });
    configs.postId = postId?.trim();;

    handleGrabArticles(`https://juejin.cn/post/${configs.postId}`)
  }
}

userId 获取所有文章

可以看到我在掘金的文章正在以一种优雅的形式输出。

3b6b993545b1e6f710baa4abb61c1be1.png

单独处理某一篇文章

再试一下,通过文章 ID 爬取,效果也是一样的。

99c0f606c34ae6ac46d1d5ae28522aed.png

最后

同样,这里的代码已经更新到了 GitHub。希望喜欢的朋友一键三连~

仓库地址:https://github.com/CrazyMrYan/node-reptile

9c090dc1d24a8c436839f4fae0e5399d.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/819395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓嵌入h5页面方法笔记

<?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><uses-featureandroid:name"android.hardware.t…

2023年的深度学习入门指南(24) - 处理音频的大模型 OpenAI Whisper

2023年的深度学习入门指南(24) - 处理音频的大模型 OpenAI Whisper 在这一讲之前&#xff0c;我们所用的大模型都是针对文本的。这一讲我们增加一个新的领域&#xff0c;即音频。我们将介绍OpenAI的Whisper模型&#xff0c;它是一个处理音频的大模型。 Whisper模型的用法 Wh…

万界星空/推出生产制造执行MES系统/开源MES/免费下载

免费MES系统介绍 什么是MES系统呢&#xff1f;MES系统主要功能就是解决“如何生产”的问题。通过实施MES系统&#xff0c;一站式解决您所困扰的所有生产制作流程问题。 普通的免费MES系统只提供简单的基本功能让客户体验&#xff0c;而万界星空MES系统运用低代码的形式开发&a…

Python初刷题笔记

目录 保留小数的方法&#xff1a;​编辑 进制问题如何转换&#xff1a; 大小写如何转换&#xff1a; 删除空格问题&#xff1a; 循环输入的简便方法&#xff1a; 截取某一部分所需要的函数&#xff1a; 字符串处理常用函数小汇总&#xff1a; sort和sorted函数的区别&am…

【Python】数据分析+数据挖掘——掌握Python和Pandas中的单元格替换操作

1. 前言 数据处理和清洗是数据分析和机器学习中至关重要的步骤。在数据处理过程中&#xff0c;我们经常需要对数据集进行清洗和转换&#xff0c;其中单元格替换是一个常用的技术。Python作为一种功能强大且灵活的编程语言&#xff0c;为数据处理提供了丰富的工具和库。Pandas库…

《你不知道的 Chrome 调试技巧》-- 学习笔记

截全屏 ctrl shift p &#xff1a;调出command 然后输入screen 效果 引用上次结果 在console中&#xff0c;想要引用上次的计算结果 使用$_ 添加有条件的断点 右击行号&#xff0c;选择 Add conditional breakpoint...(添加条件断点) 或者右击一个已经设置的断点并且选择…

GC垃圾回收器【学习笔记】

GC&#xff1a;Garbage Collectors 垃圾回收器 C/C&#xff0c;手动回收内存&#xff1b;难调试、门槛高。忘记回收、多次回收等问题 Java、Golang等&#xff0c;有垃圾回收器&#xff1a;自动回收&#xff0c;技术门槛降低 一、如何定位垃圾&#xff1f; https://www.infoq.c…

24考研数据结构-串的定义和基本实现

目录 第四章&#xff1a;串概论数据结构之串&#xff1a;定义、实现与存储结构1. 串的定义2. 串的实现方式2.1 顺序存储2.2 链式存储 3. 串的基本操作4. 串的应用结论 4.1串的定义和实现4.1.1串的定义4.1.2串的基本操作字符集编码 4.1.3串的存储结构1. 定长顺序存储表示基本操作…

海外ASO优化之通过应用商店优化来获得自然用户

应用商店优化需要我们跟踪关键词的数据&#xff0c;从而评估我们的ASO策略有效性。跟踪我们选择的时间段和国家/地区的重要搜索查询的历史排名和应用程序的最佳位置。根据我们关注的每个应用的关键词&#xff0c;位置&#xff0c;特色&#xff0c;评论和更新&#xff0c;立即了…

性能压力测试的重要性与实施方法

性能压力测试是在软件开发过程中评估系统在不同负载条件下的表现和稳定性的关键步骤。这种测试是为了确定系统在正常和峰值负载下的性能表现&#xff0c;以验证系统是否能够满足用户需求&#xff0c;同时发现潜在的性能问题并加以解决。 首先&#xff0c;性能压力测试对于确保系…

【HMS Core】融合搜索无法打开搜索服务连接问题

【关键字】 HMS、搜索服务、融合搜索 【问题描述】 有开发者反馈在集成搜索服务-融合搜索时&#xff0c;出现了无法打开搜索服务连接的问题。 严格按照官方文档集成&#xff0c;配置&#xff0c;权限已添加 searchServiceAbility .connect(new ServiceConnectCallback() { …

牛客网Verilog刷题——VL46

牛客网Verilog刷题——VL46 题目解析答案 题目 根据题目提供的双口RAM代码和接口描述&#xff0c;实现同步FIFO&#xff0c;要求FIFO位宽和深度参数化可配置。电路的接口如下图所示。   双口RAM端口说明&#xff1a; 同步FIFO端口说明&#xff1a; 双口RAM代码如下&#xff…

1、Tomcat

java介绍 Java语言和平台由以下几个主要部分组成&#xff1a; 1、Java编程语言(Java Language)&#xff1a;这是Java的核心部分&#xff0c;包括Java语法、关键字、数据类型、运算符、控制结构等。程序员使用Java语言来编写应用程序的源代码。 2、Java开发工具包(Java Developm…

企业可以申请DV https证书吗

DV https证书是有基础认证的数字证书&#xff0c;所以DV https证书也可以叫DV基础型https证书。DV基础型https证书是众多https证书中既支持个人&#xff0c;也支持企事业单位申请的https证书&#xff0c;所以企事业单位都可以申请DV基础型https证书&#xff0c;不论是企业门户网…

价值 1k 嵌入式面试题-计算机网络 OSI

开门见山 请讲下 OSI 各层协议的主要功能&#xff1f; 常见问题 回答不系统回答不确切无法和实际网络协议做关联对应 答题思路 OSI 代表了开放互联系统中信息从一台计算机的一个软件应用流到另一个计算机的另一个软件应用的参考模型 OSI 包含 7 层&#xff0c;每一层负责特…

【JavaSE】- 5min拿下泛型!

泛型 1.1 泛型的定义1.2 泛型细节2.1 泛型类2.2 泛型方法2.3 泛型接口2.4 泛型的通配符 1.1 泛型的定义 泛型的介绍 提供了编译时类型安全检测机制 泛型的好处 把运行时期的问题提前到了编译期间避免了强制类型转换&#xff0c;造成了代码的不优雅 泛型的定义格式 <类型&…

7种方法!教你如何使用Telerik UI for ASP.NET定制编辑器

Telerik UI for ASP.NET Core是用于跨平台响应式Web和云开发的最完整的UI工具集&#xff0c;拥有超过60个由Kendo UI支持的ASP.NET核心组件。它的响应式和自适应的HTML5网格&#xff0c;提供从过滤、排序数据到分页和分层数据分组等100多项高级功能。 Telerik UI for ASP.NET …

自己动手从零写桌面操作系统GrapeOS——4.1 在VirtualBox中安装CentOS

之前讲解开发环境时并没有介绍具体的安装过程&#xff0c;有网友反应CentOS的安装配置有问题&#xff0c;尤其是共享文件夹。本讲我们就来补充介绍一下在VirtualBox中安装配置CentOS的具体过程&#xff0c;彻底解决GrapeOS开发环境问题。 一、新建虚拟机 1.在VirtulBox中点击…

电脑主机启动不起来怎么回事?2023最新解决方法!

“我的电脑刚用才没多久&#xff0c;怎么主机突然就启动不起来了呢&#xff1f;试了很多方法还是不行&#xff0c;这我该怎么解决呀&#xff1f;” 在日常的学习和工作中&#xff0c;大多数人已经离不开电脑了。当然&#xff0c;在使用电脑的过程中&#xff0c;会遇到各种各样…

[Docker]入门之docker-compose

一&#xff0c;Docker-compose简介 1&#xff0c;Docker-compose简介 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是工程&#xff08;project&#xff09;&#xff0c…