内容简介:有个朋友在搞留学工作室,经常访问的一个网站叫留学者指南,然而每次都要去访问该网站,显得极其不专业。于是托俺帮忙写脚本去爬他家的东西,我观察了下,这次,我们要爬的东西就有点多了——大概就20多万个文件吧~~~在20多万个文件中,下载极有可能会被中断,因此需要做下载进度备份,下载进度恢复。那么针对这样子的需求,我们开始吧!
有个朋友在搞留学工作室,经常访问的一个网站叫留学者指南,然而每次都要去访问该网站,显得极其不专业。于是托俺帮忙写脚本去爬他家的东西,我观察了下,这次,我们要爬的东西就有点多了——大概就20多万个文件吧~~~
在20多万个文件中,下载极有可能会被中断,因此需要做下载进度备份,下载进度恢复。
那么针对这样子的需求,我们开始吧!
上代码!
const cheerio = require("cheerio"); //用于处于HTML文档流,用法类似jQuery
const http = require("http"); //用于发起请求
const fs = require("fs"); //用于检测、写入文件等其他文件操作
// "http://www.compassedu.hk/sitemap1.txt",
// "http://www.compassedu.hk/sitemap2.txt", //重复的链接
var source = [ //Robots.txt显示的数据源
"http://m.compassedu.hk/sitemap3.txt",
"http://m.compassedu.hk/sitemap4.txt",
"http://m.compassedu.hk/sitemap6.txt",
"http://m.compassedu.hk/sitemap7.txt",
"http://m.compassedu.hk/sitemap8.txt"
]
var s = 0; //控制源的序号
var arr = []; //合并的下载地址数组
var sou = []; //源下载地址数组
var i = 0; //当前下载地址数组序号
fs.exists(__dirname+"/compassedu", function(flag){ //下载路径检测
if(!flag) fs.mkdirSync(__dirname+"/compassedu"); //创建下载存放目录
})
fs.exists(__dirname+"/logs", function(flag){ //日志路径检测
if(!flag) fs.mkdirSync(__dirname+"/logs"); //创建日志存放目录
})
if(fs.existsSync(__dirname+"/logs/compassedu_backup")){ //是否存在断连恢复下载的控制文档
let obj = JSON.parse(fs.readFileSync(__dirname+"/logs/compassedu_backup")); //存在则读取上次下载的位置
i = obj.index;
init(); //开始初始化程序
}
else{
init(); //开始初始化程序
}
function init(){ //初始化
http.get(source[s], function(res){ //获取源下载地址文件
//将源文件的内容存储到数组
let rawData = "";
res.setEncoding("utf8");
res.on("data", function(chunk){ //监听数据流
rawData += chunk;
});
res.on("end", function(){ //监听结束
sou[s] = rawData.split("\n");
console.log("源", s+1, ": ", sou[s].length, "条数据");
s++;
if(s<source.length){ //源文件还未读取完
init();
}
else{ //源文件读取完毕
for(let m=0;m<sou.length;m++){ //将所有的地址数组合并
arr = arr.concat(sou[m]);
}
arr = [...new Set(arr)]; //去重
console.log("总计: ", arr.length, "条数据", "\n爬虫配置完毕!!\n开始爬取 >>");
start(); //开始爬取程序
}
});
})
}
function start(){ //开始
let url = arr[i];
console.log(url); //打印当前爬取的URL
http.get(url,function(res){ //发起请求
let obj = { //将当前的信息存储到对象中
"time": new Date().toLocaleTimeString(),
"index": i,
"url": url,
"status": res.statusCode
};
fs.appendFileSync("./logs/download.log", JSON.stringify(obj), "utf8"); //写入日志文件
fs.writeFileSync("./logs/compassedu_backup", JSON.stringify({"index": i}), "utf8"); //将当前的下载URL序号写入断连恢复文件
//读取请求到的数据流
let rawData = "";
res.setEncoding("utf8");
res.on("data", function(chunk){ //监听数据流事件
rawData += chunk;
});
res.on("end", function(){ //监听结束事件
$ = cheerio.load(rawData); //启用类jQuery插件
title = $(".container-public h1").text().replace(/\s/,"").trim(); //读取数据流部分的标题
body = $(".container-public").html(); //读取数据流部分的内容
body = body.split("visible-xs")[0]; //剥离多于的数据或其他处理,准备写入文件
i++; //序号+1
fs.writeFile(__dirname+"/compassedu/"+title+".html", body, "utf8", function(err){ //将处理好的数据写入文件
if(!err) console.log(title, "写入成功");
else{
console.log(err);
}
});
if(i>=arr.length) { //若序号达到数组的最后,结束程序
console.log("爬取结束");
fs.unlinkSync("./logs/compassedu_backup");//爬取结束,销毁断连恢复文件
return;
}
else { //否则递归运行
start();
}
});
res.on("error", function(err){ //监听其他错误
console.log(err);
});
})
}
复制代码
至此,就结束了,是否有bug还不清楚,数据还没爬完呢~
有bug的话,我后续补充修复~
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 记一次大批量物理删除数据
- 别用大批量mini-batch训练神经网络,用局部SGD!
- GPU捉襟见肘还想训练大批量模型?谁说不可以
- 从近期清风算法大批量惩罚标题作弊的企业站中学到了哪些知识
- 关于JS下大批量异步任务按顺序执行解决方案一点思考
- Scala在资源文件夹中获取文件的文件路径
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Paradigms of Artificial Intelligence Programming
Peter Norvig / Morgan Kaufmann / 1991-10-01 / USD 77.95
Paradigms of AI Programming is the first text to teach advanced Common Lisp techniques in the context of building major AI systems. By reconstructing authentic, complex AI programs using state-of-the-......一起来看看 《Paradigms of Artificial Intelligence Programming》 这本书的介绍吧!