抓取图片
本来是想写个爬虫爬一下天地图的地图图块
结果碰到了一些问题,自己总结一下
1.并发问题
其实这个不是新问题,网上也有很多解决方案,只是一开始写了个循环嵌套循环,1秒钟不到发出了90多个请求
90多个请求有时候会成功 有时候会失败
所以用了async的
async.mapLimit
解决并发问题
2.下载图块失败
本来想把失败的存在数组里全部执行完后,再从失败的数组里再次下载
之后放弃了这个想法,因为失败的还是有可能失败的
而且造成失败的原因有很多,不是单纯的让程序反复重试就可以解决问题
最后还是在生成urls数组的时候访问了一下文件夹里图块有没有成功,如果成功就跳过
3.fs模块的坑
fs.readFile是异步的
fs.readFileSync是同步的
在for循环中用同步的才可以 否则循环结束了 因为异步回调的原因 值取不到
代码如下
var request = require('request');
var fs = require('fs');
var path = require('path');
var async = require("async");
var tileMatrix = 10;
var urls = [];
var errorUrl = [];
for (var tileRow = 140; tileRow < 165; tileRow++) {
for (var tileCol = 825; tileCol < 870; tileCol++) {
var url = {
url: {
url:'http://t0.tianditu.com/img_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=c&TILEMATRIX=' + tileMatrix + '&TILEROW=' + tileRow + '&TILECOL=' + tileCol +'&FORMAT=tiles',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}
},
m: '' + tileMatrix,
r: '' + tileRow,
c: '' + tileCol
}
if(!fs.existsSync(path.join(__dirname + '/1/map/default/img', '' + url.m, url.r , url.c + '.jpg'))){
urls.push(url);
} else {
var file = fs.readFileSync(path.join(__dirname + '/1/map/default/img', '' + url.m, url.r , url.c + '.jpg'));
if (!file.length) {
urls.push(url);
}
}
}
}
async.mapLimit(urls, 20, async function(url) {
var res = await new Promise((resolve) => {
console.log('开始下载' + 'm'+ url.m +'r' + url.r + 'c' + url.c + '.jpg')
if (!fs.existsSync(path.join(__dirname + '/1/map/default/img', url.m, url.r))) fs.mkdirSync(path.join(__dirname + '/1/map/default/img', url.m, url.r));
request(url.url).on('error', function(err) {
errorUrl.push(url);
}).pipe(fs.createWriteStream(path.join(__dirname + '/1/map/default/img', url.m, url.r , url.c + '.jpg')).on('close', function(){
console.log('下载完成' + 'm'+ url.m +'r' + url.r + 'c' + url.c + '.jpg')
resolve(url);
}));
})
return res;
}, (err, results) => {
console.log('全部完成')
})
写在最后
爬虫网上有很多别人写好现成的,自己再造一遍轮子就是想踏踏坑
有时间再在github上创建个repo 把这个爬虫完善一下