这是我用18行代码写的爬虫,基于Node.j实现

如题所述

第1个回答  2024-09-04
前言

本文介绍一个简单的爬虫,是基于Node.js写的,由于我水平不高,所以写的功能不完善,实现方法比较简单,仅用于学习。

什么是爬虫

网络爬虫(又称为网页蜘蛛),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。简单来说,自动爬取目标网站内容的工具。

爬虫的原理

通过爬虫,发起网页请求,获取到网页信息,接着进行网页解析,最后根据HTML结构,获取我们想要的信息。

准备工作

需要导入三个模块:

axios:http库,可以用http模块或request代替。好处是返回的是promise对象,对我们解决异步提供了很大便利

cheerio:能让我们在服务器以jq语法操作dom(服务端的JQ)

fs:模块提供了许多非常实用的函数来访问文件系统并与文件系统进行交互

cheerio是我们的主要库,用来解析HTML,这里简单的介绍一下API:

?//?HTML模板<ul?id="fruits">??<li?class="apple">Apple</li>??<li?class="orange">Orange</li>??<li?class="pear">Pear</li></ul>//解析HTML页面$?=?cheerio.load('<ul?id?=?"fruits">...</ul>');//?selectors选择器,这里和JQ一模一样$('.apple',?'#fruits').text()?//=>?Apple$('ul?.pear').attr('class')?//=>?pear$('li[class=orange]').html()?//=>?<li?class?=?"orange">Orange</li>//?atrributes属性操作$('ul').attr('id')?//=>?fruits$('.apple').attr('id',?'favorite').html()?//=>?<li?class?=?"apple"?id?=?"favorite">Apple</li>//.each(?function(index,?element)?)遍历var?fruits?=?[];$('li').each(function(i,?elem)?{??fruits[i]?=?$(this).text();});fruits.join(',?');?//=>?Apple,?Orange,?Pear//解析和渲染$.html()//=>??<ul?id?=?"fruits">//??????<li?class?=?"apple">Apple</li>//??????<li?class?=?"orange">Orange</li>//??????<li?class?=?"pear">Pear</li>//????</ul>创建一个简易的被爬取网站

index.html

<body>??<div>????<button><a?href="http://127.0.0.1:5500/test1.html">跳转至测试页面1</a></button>????<button><a?href="http://127.0.0.1:5500/test2.html">跳转至测试页面2</a></button>????<button><a?href="http://127.0.0.1:5500/test3.html">跳转至测试页面3</a></button>????<button><a?href="http://127.0.0.1:5500/test4.html">跳转至测试页面4</a></button>????<button><a?href="http://127.0.0.1:5500/test5.html">跳转至测试页面4</a></button>??</div></body>

test1.html

<body>??<h1>第一张</h1>??<img?src="http://127.0.0.1:5500/image/bg01.jpg"?/></body>

test2.html

<body>??<h1>第二张</h1>??<img?src="http://127.0.0.1:5500/image/bg02.jpg"?/></body>

test3.html

<body>??<h1>第三张</h1>??<img?src="http://127.0.0.1:5500/image/bg03.jpg"?/></body>

被扒取的页面需要运行在服务器中,不然不能通过axios发起网络请求获取

我这里通过LiveServer将页面运行到本地服务器,端口为为:5500

效果图:

点击第一个按钮跳转页面如下:

准备爬取目标网页

我们爬取前,需要了解网页结构,知道自己需要爬取什么。

分析页面结构。我们需要扒取目标网页的图片

通过网络请求,访问页面,并解析HTML。

找到a标签中的href属性,获取属性内容,内容为另一个URL地址。

继续通过网络请求,访问页面,解析HTML。

找到img标签,获取到src中的内容。

创建一个写入流,开通文件读写通道pipe,将文件写入本地文件夹。

代码:

请求解析index页面

??let?res?=?await?axios.get('http://127.0.0.1:5500/index.html');??let?html?=?res.data;??let?$?=?cheerio.load(html);

找到a标签中href属性。通过each遍历

??$('a').each(async?(index,?element)?=>?{????$(element).attr('href')??//?成功获取所有a标签中href属性??})

继续解析请求url

??$('a').each(async?(index,?element)?=>?{????let?res?=?await?axios.get($(element).attr('href'));????let?$html?=?res.data????let?$$?=?cheerio.load($html);//成功解析请求test1.html页面结构??})

找到img标签,获取src内容,将文件写入本地

????const?$img?=?await?axios.get($$('img').attr('src'),?{??????responseType:?'stream'????});????const?ws?=?fs.createWriteStream(`./image/${index}.jpg`);//将index作为图片名称????$img.data.pipe(ws);

在本地创建image,执行代码,成功获取到图片

完整代码

const?fs?=?require("fs");const?cheerio?=?require("cheerio");const?axios?=?require("axios");(async?function()?{??let?res?=?await?axios.get("http://127.0.0.1:5500/index.html");??let?html?=?res.data;??let?$?=?cheerio.load(html);??$("a").each(async?(index,?element)?=>?{????setTimeout(()?=>?{??????var?a?=?(b?=?1);??????let?res?=?await?axios.get($(element).attr("href"));??????let?$html?=?res.data;??????let?$$?=?cheerio.load($html);??????const?$img?=?await?axios.get($$("img").attr("src"),?{responseType:?"stream"});??????const?ws?=?fs.createWriteStream(`./image/${index}.jpg`);??????$img.data.pipe(ws);??console.log(b);????},?1000);??});})();

总结

这是我做的一个简单的爬虫,核心代码只用了18行。其实方法是非常简单的,只需要分析好HTML结构,代码中修改为需要被爬取的属性,就能精准的获取想要的数据。当然,这只是个小案例,功能并不完善,如果要真正爬网页的话,至少应该加个sleep(),给它增加爬取时间间隔,或者ip代理请求,不然就...。

原文:https://juejin.cn/post/7096031446388703239

logo设计

创造品牌价值

¥500元起

APP开发

量身定制,源码交付

¥2000元起

商标注册

一个好品牌从商标开始

¥1480元起

公司注册

注册公司全程代办

¥0元起

    官方电话官方服务
      官方网站八戒财税知识产权八戒服务商企业需求数字市场
相似回答
大家正在搜