
记录自己的爬虫经验
本次是爬取某SSR网站列表页及详情页数据,包括文本及图片,将数据存入MongoDB数据库,将图片下载至本地;
首先呢,用到的nodeJs模块有:
request: 用于请求网址内容或请求图片内容 cheerio: 通俗的讲,可以当做jquery使用 pump: 一种管道, *** 纵数据流,比原生的pipe好用,可 *** 控性强,具体用法可去npm查询 path: 读取 *** 作文件路径 fs: *** 作文档读写等第一步:引入需要用到的相关模块,建议用yarn安装以下模块
const request = require("request"); const cheerio = require("cheerio"); const path = require("path"); const fs = require("fs"); const pump = require("pump"); var Bagpipe = require(‘bagpipe‘);第二步:连接Mongodb
//集合名称const colname = ‘xiaorizi‘;//1.引入模块中的客户端对象const { MongoClIEnt } = require(‘mongodb‘);const { mongo: mongourl,database } = require(‘../config.Json‘);var clIEnt,db,collection//2.利用MongoClIEnt连接数据(async function connect() { clIEnt = await MongoClIEnt.connect(mongourl,{ useNewUrlParser: true }); //连接数据库,无则自动创建 db = await clIEnt.db(database); //根据colname获取集合 collection = await db.collection(colname);})()// @增 定义写入数据库函数async function create(data) { //执行mongo增加数据语句 let result; try { result = await collection[Array.isArray(data) ? ‘insertMany‘ : ‘insertOne‘](data); } catch (err) { result = err; }}
第三步:配置需要用到的全局变量
//配置网址let base = "7595"//配置列表页数let len = 2;//配置店铺类型let lu = "film";//配置图片名称类型let lujin = "./" + lu + "/" + lu + "_";//配置请求基本网址let baseurl = "http://m.xiaorizi.me/t" + base;//生成列表页网址数组let arr = [];for (var j = 0; j < len; j++) { arr[j] = baseurl + "_p" + (j + 1) + "/";}console.log(arr);//所有页店铺数量let List_num = 0;//所有详情页图片数量let List_imgNum = 1;
第四步:开启进程
//开启10个进程爬取详情页图片var bagpipe = new Bagpipe(10);//开启4个进程爬取列表页图片var bagpipe1 = new Bagpipe(4);//记录爬取成功的详情页图片数量var index = 1;//定义下载图片函数function downloadImage(src,dest,callback) { request.head(src,function (err,res,body) { // console.log(‘content-type:‘,res.headers[‘content-type‘]); // console.log(‘content-length:‘,res.headers[‘content-length‘]); if (src) { var source = request(src); pump(source,fs.createWriteStream(dest)).on(‘close‘,function () { callback(null,dest); }); } })}
第五步:遍历所有页面,爬取列表页及详情页
//遍历所有页for (var g = 0; g < arr.length; g++) { //请求单页 request(arr[g],async (error,response,body) => { //载入网站内容至body let $ = cheerio.load(body); // 利用jquery的核心方法获取HTML代码中的具体元素 await $(‘.shops>li‘,‘body‘).each(async (i,e) => { //标题 let List_Title = $(e).find("h3").text(); //店铺 let List_store = $(e).find(".tag").text(); //地址 let List_address = $(e).find("p").last().text(); //图片src let List_imgSrc = $(e).find("a").first().find("img").attr("data-original"); if (List_imgSrc) { //获取图片后缀名 let back1 = path.basename(List_imgSrc).match(/[\.].+/); //将图片改名 let List_imgname = lujin + List_imgNum++ + back1; //图片名称 let List_img = path.basename(List_imgname) //爬取列表页图片 await bagpipe1.push(downloadImage,List_imgSrc,List_imgname,async (err,data) => { //爬取详情页面 let detailSrc = "http://m.xiaorizi.me" + $(e).find("a").first().attr("href"); await request(detailSrc,bodys) => { let $2 = cheerio.load(bodys); //如果详情页存在 if ($2(".Title_h")) { List_num++; //标题 let detail_Title = []; detail_Title[0] = $2(".Title_h").text(); detail_Title[1] = $2(".Title_p").text(); console.log("第" + List_num + "个店铺:",List_store) //店铺详情 let detail_shop = []; $2(".shop_detail li").each((i) => { detail_shop[i] = $2($2(".shop_detail li")[i]).text(); }) //主要内容 let detail_cont = []; //详情页图片数量 let detail_imgNum = 0; //详情页文本及图片 $2(".content").children().each((i,e) => { //如果到达底部结束标签p1则停止爬取 if ($2(e).prop("classname") == "p1") { return; } //单个文本对象或图片对象 let obj = {}; obj.tagname = $2(e).prop("tagname"); if (obj.tagname == "P") { obj.value = $2(e).text(); //如果P标签有内容再推入detail_cont数组 if (obj.value != "") { detail_cont.push(obj); } } else if (obj.tagname == "img") { //获取图片地址 let detail_imgSrc = $2(e).attr("src"); //匹配图片后缀名 let back2 = path.basename(detail_imgSrc).match(/[\.].+/); //定义图片路径及名称 let detail_imgname = lujin + "d_" + List_num + "_" + ++detail_imgNum + back2; obj.value = path.basename(detail_imgname); detail_cont.push(obj); //爬取详情页图片 bagpipe.push(downloadImage,detail_imgSrc,detail_imgname,(err,data) => { console.log("[" + index++ + "]:" + data); }) } }) create({ city: List_store.split(" ")[0],type: List_store.split(" ")[1],List_img,List_Title,List_store,List_address,detail_Title,detail_shop,detail_cont }) } else { console.log("详情页不存在:" + List_store) } }) }) } }) })}
备注:config.Json配置如下
{ "PORT": 19011,"mongo": "mongodb://localhost:27017","database": "runoob"}总结
以上是内存溢出为你收集整理的nodeJS(request+cheerio+pump)稳定爬取SSR网页数据全部内容,希望文章能够帮你解决nodeJS(request+cheerio+pump)稳定爬取SSR网页数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)