nodejs抓取动态网页(一个网络爬虫的开发过程及实现过程原理目标分析 )
优采云 发布时间: 2021-10-06 05:20nodejs抓取动态网页(一个网络爬虫的开发过程及实现过程原理目标分析
)
Nodejs 将前端开发语言移植到了服务端。如今,前端开发者可以轻松地使用 Nodejs 实现网络爬虫,这在以前是不可想象的。本文介绍了一个简单的Nodejs爬虫开发过程,只想看代码拉到最后。
爬行原理目标分析
这次爬取的目标选择是观察cnBeta的新闻详情页收录到相邻页面的链接,但是通过查看源码,发现这个链接是由Js生成的:
这是一种常见的反爬虫措施。关联页面的链接通过异步请求获取,然后由js动态生成。查看网络面板,您可以看到该页面确实发送了一个异步请求。结果具有我们想要的关联页面 ID:
接下来分析这个请求,可以发现有两个参数,这两个参数都可以在HTML中找到:
第一个参数_csrf很容易直接在源码中搜索:
第二个参数全文搜索找不到:
观察这个参数的结构,发现数据被两个逗号分隔成三段,所以猜测数据是由于多部分拼接造成的,单独搜索真的找到了:
但是我只找到了最后两段数据,开头是1,不知道是哪里来的。由于只有一个字符,检索起来比较困难,观察到这个请求在很多页面中都是以1开头的,所以这里干脆写死了。. .
至此,对目标的分析结束,下面将执行爬虫。
实施过程程序结构
大体思路是从起始页开始爬取,异步获取上一个新闻页面的链接继续爬取,并设置最大爬取次数,防止陷入死循环。伪代码如下:
功能点
关键是保存内容。首先,获取页面的 HTML 代码。主要使用http模块,如下:
const http = require('http');
http.get(pageUrl, function(res){
let html='';
res.setEncoding('utf8');
res.on('data', (chunk) => {
html += chunk;
});
res.on('end', () => {
console.log(html); //这里得到完整的HTML字符串
});
})
复制代码
要从 HTML 获取信息,您可以使用常规匹配,或使用cheerio。Cheerio 可以说实现了一个 Nodejs 端的 jQuery。它和jQuery的区别在于它需要先生成一个实例,然后像jQuery一样使用它:
const cheerio = require('cheerio');
const $ = cheerio.load(html);
let news_title = $('.cnbeta-article .title h1').text().trim().replace(/\//g, '-');
复制代码
fs模块主要用于保存文件,如下:
const fs = require('fs');
fs.writeFile(FilePath, FileContent, 'utf-8', function(err) {
if (err) {
console.log(err);
}
});
复制代码
这里有个坑。我们希望将文章的文本保存为与标题同名的txt文本,但标题可能收录斜线(/)。保存这样的文件时,程序会把标题斜线前的部分误认为是路径,报错,所以需要替换标题中的斜线。
保存图片与保存文本大致相同。主要区别在于写入格式,需要以二进制方式写入:
http.get(img_src, function(res) {
let imgData = "";
res.setEncoding("binary"); //注意格式
res.on("data", function(chunk) {
imgData += chunk;
});
res.on("end", function() {
fs.writeFile(imgSavePath, imgData, "binary", function(err) { //注意格式
if (err) {
console.log(err);
}
});
});
复制代码
程序的结构和主要功能基本是这样的。
后记
实现爬虫说起来容易,但是健壮性真的很难保证。在爬cnBeta的过程中,又发现了一个301跳坑。URL跳转时,程序抓取的HTML为空,无法获取。因此,请求得到响应后,需要判断响应头是否为301,如果是,则需要从响应信息中找到重定向后的URL,重新发起请求。好在cnBeta不需要用户登录,如果是必须登录才能访问的网站,爬虫会很麻烦。
本项目完整代码见Nodejs爬虫,感谢cnBeta^^。