来一条node爬虫

五分钟学会Python网络爬虫 但不管怎样,爬虫技术是无罪的,还是值得我们开发人员去学习了解一下的。在学习之前,我们还是要先了解一下相关概念。 什么是爬虫 网络爬虫:又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。 大数据时代,要进行数据分析,首先要有数据源,可数据源从哪里来,花钱买,没预算,只能从其它网站就行抓取。 细分下来,业内分为两类:爬虫和反爬虫。 反爬虫:顾名思义,就是防止你来我网站或APP上做爬虫的。 爬虫工程师和反爬虫工程师是一对相爱相杀的小伙伴,经常因为对方要加班写代码, 阅读详情

用node写个爬虫真的肥肠煎蛋,今天就来玩一下。

物料

首先准备物料。

cnpm i axios
cnpm i cheerio

我们需要准备两个第三方包,一个是axios,用来发送请求的,当然request包也行,看个人喜好了;另一个是cheerio,这货是用来解析dom的,跟jquery的用法一样一样的。

爬虫的实现思路

也就是说,我们通过axios请求过来的html的标签数据,然后用cheerio包来提取我们需要的内容,紧接着我们可以用fs包的流来读取数据,然后写入我们的磁盘,这就是一个完整的爬虫需要做的事情。

预热

先预热一下。

const axios = require('axios');
const cheerio = require('cheerio');

let httpUrl = 'http://www.adoutu.com/picture/list/1';

axios.get(httpUrl).then(res=>{
    // console.log(res.data); //获取数据
    let $ = cheerio.load(res.data); //将dom节点导入cheerio解析
    $('.list-group .list-group-item a').each((i,ele)=>{ // 遍历dom节点
        let url = $(ele).attr('href'); //获取a标签的href属性信息
        console.log(url);
    })
})

实现

预热完毕,开始干活。

const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
let httpUrl = 'http://www.adoutu.com/picture/list/1';

axios.get(httpUrl).then(res=>{
    // console.log(res.data); //获取数据
    let $ = cheerio.load(res.data);
    $('.list-group .list-group-item a').each((i,ele)=>{ // 遍历dom节点
        let aUrl = $(ele).attr('href'); //获取a标签的href属性信息
        
        parsePage('http://www.adoutu.com' + aUrl);
    })
})

async function parsePage(url) {
    let res = await axios.get(url);
    let $ = cheerio.load(res.data);
    let imgUrl = $('.detail-picture img').attr('src');
   
    let urlObj = path.parse(imgUrl);
    let ws = fs.createWriteStream(`./img/${urlObj['name']}${urlObj['ext']}`);
    axios.get(imgUrl,{responseType:'stream'}).then(res=>{ //指定获取二进制流
        res.data.pipe(ws);
        res.data.on('close',()=>{
            ws.close();
        })
    })
}

分页

如果有分页,我们可以先获取分页总数,然后循环发请求即可。

const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');

let httpUrl = 'http://www.adoutu.com/picture/list/1';

spider();
//循环发起请求
async function spider() {
    let page = await getNum(); 
    for (let i = 1; i <= page; i++) {
        if(i < 5) // 如果page太大,会存在崩溃问题
            getData(i)
        else 
            break;    

    }
}
//获取每页数据
async function getData(page) {
    let url = 'http://www.adoutu.com/picture/list/' + page;
    console.log(url);
    let res = await axios.get(url);
    let $ = cheerio.load(res.data);

    $('.list-group .list-group-item a').each((i, ele) => { // 遍历dom节点
        let aUrl = $(ele).attr('href'); //获取a标签的href属性信息
        // console.log(aUrl);
        parsePage('http://www.adoutu.com' + aUrl);
    })

}
// 获取分页数
async function getNum() {
    let res = await axios.get(httpUrl);
    let $ = cheerio.load(res.data);

    let count = $('.pagination li').length;
    // console.log(count);
    let pageNum = $('.pagination li').eq(count - 2).find('a').text();
    // console.log(pageNum);
    return pageNum;
}
//解析并存储数据
async function parsePage(url) {
    let res = await axios.get(url);
    let $ = cheerio.load(res.data);
    let imgUrl = $('.detail-picture img').attr('src');

    let urlObj = path.parse(imgUrl);
    let ws = fs.createWriteStream(`./img/${urlObj['name']}${urlObj['ext']}`);
    axios.get(imgUrl, { responseType: 'stream' }).then(res => {
        res.data.pipe(ws);
        res.data.on('close', () => {
            ws.close();
        })
    })
}

延迟执行

上面我们发现了一个问题,就是分页过多的情况下,程序就会报错,为什么呢?
因为我们一次性发送的请求太多了,for循环是同步执行的,刷的一下发那么多请求,不挂才怪。怎么办呢?
这问题能难倒你吗?让他延迟执行呗。
不过请注意,这个延迟执行也没那么简单,比如这么写:

async function spider() {
    let page = await getNum(); 
    for (let i = 1; i <= page; i++) {
       setTimeout(()=>{
        getData(i)  
       },2000); 

    }
}
...

这么写是不行的,因为这就等于你在事件队列中创建了n个getData()函数,然后等待2s后执行这n个getData()函数,其实还是同时执行的。
那怎么搞?
我们可以让请求拉开距离执行:

async function spider() {
    let page = await getNum(); 
    for (let i = 1; i <= page; i++) {
       setTimeout(()=>{
        getData(i)  
       },2000*i); 

    }
}

这样写还是在事件队列建立了n个getData(),不过他们的执行时间不一致了,分别是等待2s、4s…依次类推的执行,这样就拉开了请求之间的距离。
这个等待场景还是蛮常用的哈,写那么多定时器还是很烦人的哈,我们可以将这个逻辑用promise封装起来。

//等待
function sleep(time){
    var timer;
    return new Promise((resolve,reject)=>{
        timer = setTimeout(()=>{
            clearTimeout(timer);
            resolve('请求延迟'+time)
        },time)
    })
}

然后我们利用这个等待函数就可以写出比较优雅的代码了:

const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');

let httpUrl = 'http://www.adoutu.com/picture/list/1';

spider();
//循环发起请求
async function spider() {
    let page = await getNum(); 
    for (let i = 1; i <= page; i++) {
        await sleep(2000*i) //每个请求等待2s、4s....后执行
        getData(i) 

    }
}
//等待
function sleep(time){
    var timer;
    return new Promise((resolve,reject)=>{
        timer = setTimeout(()=>{
            clearTimeout(timer);
            resolve('请求延迟'+time)
        },time)
    })
}
//获取每页数据
async function getData(page) {
    let url = 'http://www.adoutu.com/picture/list/' + page;
    console.log(url);
    let res = await axios.get(url);
    let $ = cheerio.load(res.data);

    $('.list-group .list-group-item a').each(async (i, ele) => { // 遍历dom节点
        let aUrl = $(ele).attr('href'); //获取a标签的href属性信息
        // console.log(aUrl);
        await parsePage('http://www.adoutu.com' + aUrl);
    })

}
// 获取分页数
async function getNum() {
    let res = await axios.get(httpUrl);
    let $ = cheerio.load(res.data);

    let count = $('.pagination li').length;
    // console.log(count);
    let pageNum = $('.pagination li').eq(count - 2).find('a').text();
    // console.log(pageNum);
    return pageNum;
}
//解析并存储数据
async function parsePage(url) {
    let res = await axios.get(url);
    let $ = cheerio.load(res.data);
    let imgUrl = $('.detail-picture img').attr('src');

    let urlObj = path.parse(imgUrl);
    let ws = fs.createWriteStream(`./img/${urlObj['name']}${urlObj['ext']}`);
    axios.get(imgUrl, { responseType: 'stream' }).then(res => {
        res.data.pipe(ws);
        res.data.on('close', () => {
            ws.close();
        })
    })
}
2024年最全如何结合Node和Puppeteer做网络爬虫 那么怎么判断爬虫是不是违法呢?关于爬虫是否非法其实没有很明确的说法,一直都是中立的态度。爬虫是一种技术,技术本身没有违法的。但是你使用这种技术去爬取不正当的信息、有版权的图片等用于商用,那么你就是违法了。其实我们只要在使用爬虫技术的时候不要去爬个人隐私信息,不要爬取有版权的图片,最重要的是信息不要用于商业化的行为,爬虫不得干扰网站的正常运行等。说了这么多其实就是要大家谨慎使用这一项技术。 阅读详情

相关推荐

【网络爬虫技术入门-搭建网络爬虫开发环境】

本系列文章是作者学习网络爬虫技术过程中的笔记,记录作者实操过程给读者作为学习网络爬虫技术的入门参考。本章记录作者搭建学习网络爬虫技术的开发环境全过程。本文以作者开发环境为例,介绍了在Windows 10环境下安装配置网络爬虫的开发环境。本环境使用VS Code作为编辑平台,配合python和Node.js开发工具,是后续网络爬虫实践课程的实验基础,在进行后续课程前务必成功配置好此开发环境。

maotaolaodie的博客 853

浅谈Axios和(async/await)

await 也是一个修饰符,只能放在async定义的函数内。await 关键字仅在 async function 中有效。如果在 async function 函数体外使用 await ,你只会得到一个语法错误。Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。通过 params 设置参数,实际开发中常用。通过 data 设置参数,data可以省略。async/await 是ES7提出的基于。的解决异步的最终方案。

Growing up Or Growing old 1548

Open UI5 源代码解析之1259:FilterBar.js

本文详细解析了SAP OpenUI5项目中FilterBar.js文件的实现原理。该文件位于卡片系统的过滤器模块中,主要功能是组织和管理过滤器控件,协调其可见性状态。文章从文件定位、依赖关系、类定义、渲染逻辑、初始化过程、资源清理等方面进行了深入分析,揭示了其作为轻量级组织者的设计理念。特别强调了该组件通过观察器模式实现自治管理,以及其适配不同布局容器的实现策略。通过类比商场信息屏、机场安检等场景,生动说明了该组件的设计思路及其在UI5框架中的关键作用。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 714

Axios介绍与应用

Axios是一个基于Promise的现代化HTTP客户端库,既可以在浏览器端使用,也可以在Node.js环境中使用。它支持所有主流的浏览器,包括IE8+,并提供了许多易用的特性和配置选项,使得发送HTTP请求和处理响应变得更加简单和可控。Axios还支持取消请求、拦截请求和响应、转换请求和响应数据等高级功能,是目前最为流行和实用的HTTP客户端之一。在本次的团队项目当中,由于是第一次进行Axios的编写,起初是不太适应的,但是随着慢慢学习,Axios也越发的容易上手,并且可以进行操作。

ajskx的博客 489

Node.js网络爬虫与搜索引擎实战项目

本文还有配套的精品资源,点击获取 简介:本项目"search-engine"展示了如何使用Node.js实现网络爬虫和搜索引擎。通过学习这个项目,开发者可以理解网络爬虫和搜索引擎的基本原理以及在JavaScript环境下的实现方法。项目包括网络爬虫的自动网页遍历和数据抓取,以及对收集数据进行索引、存储和检索的搜索引擎。项目的结构和配置,如依赖管理、源代码存放、配置文件、日志...

weixin_42430341的博客 2040

基于Node.js的高效网络爬虫实战案例

简介:网络爬虫是IT领域中用于自动抓取互联网信息的重要技术。本“node.js爬虫例子”项目利用Node.js这一高性能JavaScript运行环境,结合superagent、cheerio和async等核心库,实现高效的网页数据抓取。通过superagent发送HTTP请求,cheerio解析HTML内容提取目标数据,以及async库管理异步流程,避免回调地狱并提升代码可维护性,项目展示了构建轻量级爬虫的完整流程。

weixin_32687875的博客 1398

axios请求方法封装

axios 介绍;axios 特性;axios 安装;axios 执行 get 请求;axios 执行 post 请求;axios API;创建 axios 实例;axios 实例配置;axios 请求方法封装;axios 请求方法使用;

taoqidejingling的博客 1232

从选型到阵列:基于ESP32-S3的智能硬件麦克风系统设计实战

本文详细介绍了基于ESP32-S3芯片设计智能硬件麦克风阵列的完整实战方案。从核心芯片选型、数字MEMS麦克风的参数解读与电路设计,到关键的声学结构密封、阵列布局策略,再到利用ESP-ADF框架构建音频处理流水线并集成回声消除、噪声抑制等算法,提供了从硬件到软件的全链路设计指南与避坑要点,旨在实现清晰、稳定的远场语音交互。

weixin_29173777的博客 268

2021-06-21 axios 实现网络请求并使用nodejs实现代理

安装 npm i -S axios 上线用S下载依赖包 不上线用D 在需要的组件中写ajax 引入 axios 库 import axios from "axios" //const url = https://api.iynn.cn/film/api/v1/getNowPlayingFilmList? cityId=320900&pageNum=1&pageSize=10 const url = 'http://localhost:4000/api/g...

pyy88888的博客 1135

Slurm集群调度策略详解(1)-主调度

Slurm调度系统中针对作业的调度主要有三种,主调度,回填调度,GANG调度,这篇文章主要针对主调度进行解析。

h_m_l的博客 6031

华硕ROG枪神双系统实战:Ubuntu安装避坑指南

本文是华硕ROG枪神笔记本安装Ubuntu双系统的详细避坑指南。针对其独特的硬件与BIOS设计,文章核心解决了VMD控制器导致硬盘无法识别、驱动兼容性等关键难题,并提供了从BIOS设置、分区方案到安装后驱动配置与性能调优的一站式解决方案,帮助用户实现稳定的双系统体验。

raspberrypi5的博客 546

node JS獲取GPS_如何系统的学习Node.js?

01Node作为前端“拓展地盘”的必备工具,可以说是前端程序员想要发展成为全栈工程师最不可少的工具了。但是如何系统的学习Node.js呢?对于正在准备的小伙伴,我们这次就给大家一个学习Node的建议。02是看书看文档还是找项目练手呢?这是根据自己的习惯而定的。因为单纯的看书并不能完全的运用,我比较推荐的是先开始做项目,在遇到问题了的时候去针对性的找到文档内容进行研究,或者在空闲的时间(公交车上或者...

weixin_39749243的博客 187

AI算力网络与通信领域流量分析:优化策略探讨_副本

今天的AI就像一个"超级吃货",每天要"吃"掉海量数据、“消耗"巨量算力——训练一个千亿参数的大模型,可能需要上万块GPU同时工作数周,其间产生的数据传输量足以填满数百万个1TB硬盘。这些GPU和计算节点通过网络连接形成"AI算力网络”,而数据在节点间的流动就是"通信流量"。如果把算力比作AI的"肌肉",那流量就是"血液"——血液不通畅,肌肉再强也使不上劲。

AI天才研究院 1201

网络爬虫技术

本文介绍了网络爬虫的基础概念与应用。主要内容包括:1)爬虫定义与分类,分为通用、聚焦、增量式和深层网络爬虫四种类型;2)核心工作原理,涉及HTTP请求过程、响应结构和网页基础;3)常见爬取策略如宽度优先(BFS)和深度优先(DFS)遍历;4)Python中Requests库的使用方法,包括请求发送、响应处理和异常捕获。文章通过百度网页爬取实例,展示了网络爬虫从发送请求到获取响应的完整流程,为初学者提供了网络数据采集的基础知识框架。

2302_78993464的博客 2959

Chroma向量数据库实战:用Python快速搭建本地知识库(附中文诗词检索案例)

本文详细介绍了如何使用Chroma向量数据库和Python快速搭建本地知识库,并附有中文诗词检索的实战案例。通过解析核心概念、数据准备、向量化及智能检索实现,展示了Chroma在处理中文语义搜索时的轻量级与易用性,为开发者构建AI应用原型提供了实用指南。

weixin_29221753的博客 480

AI 智能体(Agent)应用开发工程师 · 进阶面试 (五)

在有多位 Agent 共同参与决策时(如评审委员会、代码审查小组),它们可能提出截然相反的建议。共识机制就是用来在这种冲突中得出唯一行动方案的规则。常用机制:多数投票:每个 Agent 一票,根据投票结果决定。实现简单,但忽略了专业度差异。加权投票:根据 Agent 的角色重要性或历史表现赋予不同权重,例如首席架构师 Agent 的票权重是普通开发者 Agent 的 2 倍。管理者仲裁:由一个权限更高的 Manager Agent 听取各方理由后做出最终裁决。这类似于层级制组织决策。辩论收敛。

篮球界最会写bug的人;程序猿中打球最菜的人。 397

【愚公系列】《Python网络爬虫从入门到精通》001-初识网络爬虫

随着互联网的快速发展,数据的获取与处理变得愈发重要。在这个信息爆炸的时代,如何有效地收集和利用网络上的海量数据,成为了各行业面临的一大挑战。网络爬虫,作为一种自动化获取网页信息的技术,正逐渐成为数据分析、市场研究、竞争对手监控等领域不可或缺的工具。本文将带领读者初步了解网络爬虫的基本概念、工作原理以及常见应用场景。我们将探讨爬虫的构建过程,包括如何发送请求、解析网页、存储数据等关键步骤。同时,还会涉及一些爬虫开发中的注意事项,如如何遵循网站的robots.txt协议、避免被封禁等。

愚公智库 12万+

第一节:从Chat_Bot 到 AI_Agent——一个范式转换

本文系统剖析了工业级AI代理系统ClaudeCode的设计原理与工程实践。通过对比ChatBot与Agent的三个本质差异:自主循环决策vs单轮应答、环境交互vs纯文本I/O、持久状态管理vs无状态对话,揭示了构建生产级Agent系统的关键挑战。文章详细解析了ClaudeCode的五层架构设计、1800+文件组成的运行时系统,包括工具调度、权限管理、状态持久化等核心机制,并阐述了从简单API调用到完整Agent系统的演进路径。

2201_75869398的博客 69

Node.js实现简单爬虫 讲解

一、什么是爬虫 网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。 搜索引擎 今日头条/网易新闻 .抢票软件 最终都指向的是 12306 比价网 ·淘宝 京东 拼多多 在生活中网络爬虫经常出现,搜索引擎就离不开网络爬虫。例如,百度搜索引擎的爬虫名字叫作百度蜘蛛(Baiduspider)。百度蜘蛛,是百度搜索引擎的一个自动程序。它每天都会在海量的互联.

woyebuzhidao321的博客 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

6个必备的 Node 网络爬虫库

作为一名程序员,你是否曾遇到过需要从各大网站提取数据的需求? 随着互联网的快速扩展,能够高效地进行网络爬虫已经成为企业、 研究人员以及个人的一项重要技能。在这个数据为王的时代, 如何利用JavaScript和Node.js来实现高效的数据抓取, 是每一个开发者都应该掌握的技巧。网络爬虫,即从网站提取数据的过程,已经成为各行各业的重要工具。而JavaScript和Node.js因其强大的功能和丰富的...

zz_jesse的博客 1478

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

干货:一文看懂网络爬虫实现原理与技术(值得收藏)

01网络爬虫实现原理详解不同类型的网络爬虫,其实现原理也是不同的,但这些实现原理中,会存在很多共性。在此,我们将以两种典型的网络爬虫为例(即通用网络爬虫和聚焦网络爬虫)...

Python大本营的博客 5万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Node.js 爬虫技术:构建高效网络爬虫的全面指南

本文全面介绍了在 Node.js 环境下构建网络爬虫的技术和实践。从基础的爬虫概念到 Node.js 环境的搭建,再到使用 axios 和 request 库进行数据请求、解析 HTML 和 JSON 数据,以及遵守 Robots 协议的重要性。文章还涵盖了错误处理、重试机制、异步控制和并发请求的实现,提供了详细的代码示例和最佳实践。最后,强调了在使用爬虫技术时应尊重版权和法律,确保技术使用的合法性和道德性。通过本文,读者将获得构建和维护高效、可靠 Node.js 爬虫所需的知识和工具。

x15514104477的博客 2379

快速带你学会Python网络爬虫

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。如上图所示,爬虫的第一个步骤就是对所要爬取的网页进行请求,以获取其相应返回的结果,然后在使用一些方法,对响应内容解析,提取想要的内容资源,最后,将提取出来的资源保存起来。目前爬虫这块用的最多的是python,因为python语法简洁,方便修改,而且python里有多爬虫相关的库,拿过来就可以使用,网上的资料也比较多。

weixin_67991858的博客 706

Node.js网站爬虫(三)网络爬虫

文章目录1 对目标网站进行分析:1.1 分析网页html结构1.1.1 主页:1.1.2 新闻详情页:1.2 其他方式:2 爬取结构与工具包:2.1 爬取整体结构:2.2 工具包2.2.1 模块下载和导入模块:3.0.2 工具包(重要模块):3 爬取流程:3.1 定义format:3.1.1 根据html结构使用CSS选择器:3.1.2 设置正则表达式3.2 配置异步执行和定时执行等:3.3 读取种子页面:3.4 读取新闻页面:3.4.1 转码并获取内容:3.4.2 动态执行format字符串,构建jso

weixin_42453922的博客 1258

推荐6个最好的 JavaScript 和 Node.js 自动化网络爬虫工具!

在这篇文章中,我们将深入探讨6个最好的JavaScript和Node.js网络爬虫库,分析它们的功能、优点和缺点。无论你是初学者还是高级用户,这篇指南都将为你选择合适的网络爬虫解决方案提供宝贵的知识和见解。

software_test010的博客 2270
上一篇: node如何连接mysql?
下一篇: git冲突解决方案
姜治宇
博客等级 码龄10年 1粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值