nodejs抓取动态网页(年前无心工作,上班刷知乎发现一篇分享python爬虫的文章)
优采云 发布时间: 2022-03-17 08:26nodejs抓取动态网页(年前无心工作,上班刷知乎发现一篇分享python爬虫的文章)
多年前无意工作,在工作中发现一篇文章分享python爬虫刷知乎的文章。
感觉他爬的网站里面的妹子都好看,很喜欢这里,个个都是美女。
不幸的是,虽然python已经使用了很长时间,但是它已经被废弃太久了。最近在用nodejs重构后台界面,所以尝试用nodejs实现爬虫。
好吧,让我们开始吧,男孩!
准备好工作了:
系统环境:mac
运行环境:节点
所需模块:request-promise、cheerio、fs
编辑:vscode(谁用谁知道)
简单看一下这些 nodejs 模块:
var request = require('request-promise');
request('http://www.google.com')
.then(function (htmlString) {
console.log(htmlString)
})
.catch(function (err) {
});
任何响应都可以输出到文件流:
request('http://google.com/doodle.png').pipe(
fs.createWriteStream('doodle.png')
)
api类似jQuery,使用超级简单
const cheerio = require('cheerio')
const $ = cheerio.load('Hello world')
$('h2.title').text('Hello there!')
$('h2').addClass('welcome')
$.html()
//=> Hello there!
您可以在本地创建目录、创建文件、读取文件等。
网页分析:
分析目标的相册网址网站
因为python文章的作者已经详细分析过网站,我就简单分析一下。
随意打开几张相册,可以看到规则如下:
"https://www.****.com/g/****/"
所以我们可以确定要爬取的base url:
const base_url = 'https://www.****.com/g/';//爬取相册网页的基本网址
然后看几乎每张专辑底部的页码,而我们要抓取整张专辑,所以需要考虑分页情况,点击分页,我们看到分页的url是这样的:
"https://www.****.com/g/****/*.html"
商业逻辑:
实际代码:
app.js 轮询和代码结构
const nvshens = require('./co');
const base_url = 'https://www.nvshens.com/g/';//爬取相册网页的基本网址
let index = 1;
let start = 25380;
const end = 30000;
const main = async (URL) => {
//1.请求网址
const data = await nvshens.getPage(URL);
//2.判断是否存在相册
if (nvshens.getTitle((data.res))) {
//3.下载照片
await nvshens.download(data.res);
//4.请求分页
index++;
const new_url = `${base_url}${start}/${index}.html`;
main(new_url);
} else {
index = 1;
console.log(`${base_url}${start}页面已完成`)
start++;
if (start < end) {
//5.请求下一个网址
main(base_url + start);
} else {
console.log(`${base_url}${end}所有页面已完成`)
}
}
};
main(base_url + start);
co.js //业务代码
var request = require('request-promise'); //网络请求
const cheerio = require("cheerio");//操作dom
const fs = require("fs");//读写文件
const headers = {
"Referer": "https://www.nvshens.com/g/24656/"
}
//因为一些网站在解决盗链问题时是根据Referer的值来判断的,所以在请求头上添加Referer属性就好(可以填爬取网站的地址)。
//另外Referer携带的数据 是用来告诉服务器当前请求是从哪个页面请求过来的。
const basePath = "/Users/用户名/Desktop/mm/";
//自定义mac本地下载目录,需预先创建,windows路径可参考"D:/Users/mm/"
let downloadPath;
let pageIndex = 1;
module.exports = {
//请求页面
async getPage(url) {
const data = {
url,
res: await request({
url: url
})
}
return data;
},
//判断页面是否存在相册
getTitle(data) {
const $ = cheerio.load(data);
if ($("#htilte").text()) {
downloadPath = basePath + $("#htilte").text();
//创建相册
if (!fs.existsSync(downloadPath)) {
fs.mkdirSync(downloadPath);
console.log(`${downloadPath}文件夹创建成功`)
}
return true;
} else {
return false;
}
},
//下载相册照片
async download(data) {
if (data) {
var $ = cheerio.load(data);
$("#hgallery").children().each(async (i, elem) => {
const imgSrc = $(elem).attr('src');
const imgPath = "/" + imgSrc.split("/").pop().split(".")[0] + "." + imgSrc.split(".").pop();
console.log(`${downloadPath + imgPath}下载中`)
const imgData = await request({
uri: imgSrc,
resolveWithFullResponse: true,
headers,
}).pipe(fs.createWriteStream(downloadPath + imgPath));
})
console.log("page done")
}
},
}
开始运行
node app.js
可以实现几个功能,是不是很简单?