众所周知,写爬虫都是用的python
或者 java
或者 scala
,然而作为菜逼的我,当然也会随波逐流?NONONO,常在河边走,哪能不湿鞋?对不起,我穿的雨靴!老子八块五买的一双!
使用js网络爬虫下载图片或者任何带有下载链接的内容时,能下载文件的原理:本质上来说,没有使用原生javascript进行网络爬虫下载数据的,一般使用的时js对html结构的提取的高效性作为爬虫时的优势,相比于python爬虫而言,其js爬虫对数据解析能力较弱,其数据处理的类库也没有python丰富(毕竟python作为公认的专业的数据处理语言),通常情况下,使用python爬虫进行下载文件时,只需要在html中解析出我们需要的对应的下载链接即可利用:
download_url = 'xxxxxxx' # 假设这是我们通过某些手段解析出来的下载链接
request = requests.get(download_url);
with open(filename, 'wb') as file:
file.write(request.content);
大致按照上述的代码就能实现文件的下载,图片或者文件都行。大致的原理是使用IO流的方式,将流存储到本地中,保存方式为 wb
使用js下载文件的代码演示:
download_url = 'xxxx'
let a = document.createElement('a');
a.id = 'xx' // 自定义的id
a.href = download_url // 下载链接
a.download = 'xxx' // 自定义即可
a.click()
利用js爬虫下载文件的原理是使用a标签的download属性,如果为a标签设置了download属性,出发a标签的点击事件就会下载a标签的href中的下载地址。
所以我们要做的就是设置虚拟dom,然后为设置的dom设置我们需要的属性,点击a即可。
建议将最后的下载地址存储到一个数组中,在程序的最后循环点击对应的虚拟dom下载即可,要注意的是生成的dom是需要设置标志性的id或者class,以便于在循环中以此取出对应的dom执行click从而实现对应的文件的下载,执行循环的时候最好设置一个timeout,如何在循环中套用timeout而不影响程序的同步执行?使用:
let i = 0;
interval = setInterval(() => {
if (i < download_.length) {
document.getElementById(download_[i]).click();
i ++ ;
} else {
clearInterval(interval);
}
}, 500);
替代for循环的作用,便于理解,同步执行。
整体代码:
let pageTotalNum = prompt('请输入要爬取的页数:');
let pageList = new Array(45).fill(0);
let linkList = [];
let download_ = [];
pageList.forEach((item, index) => {
pageList[index] = index + 1;
});
pageList.forEach((pageNum) => {
if (pageNum == 1) {
linkList.push('https://sc.chinaz.com/jianli/fengmian.html');
} else {
linkList.push('https://sc.chinaz.com/jianli/fengmian_' + pageNum + '.html');
}
});
get_html = function(url) {
let http = new XMLHttpRequest();
http.open('get', url, false);
http.send();
return http.response;
}
parse_html = function(reg_str, html) {
let reg = reg_str;
let result;
let second_url = [];
while ((result = reg.exec(html)) !== null) {
second_url.push(result[1]);
}
return second_url;
}
function main() {
for (let url of linkList) {
let reg_1 = /<div class="box col3 ws_block" style="width:219px.*?">.*?<a target="_blank" href="(.*?)">/igs;
let html_1 = get_html(url);
let url_2 = parse_html(reg_1, html_1);
for (let item of url_2) {
let new_url = 'https:' + item;
download_url = parse_html(/<li><a href='(.*?)'/igs, get_html(new_url));
let set = new Set(download_url);
for (let d_url of set) {
let a_node = document.createElement('a');
a_node.id = d_url;
document.body.appendChild(a_node);
a_node.href = d_url;
a_node.download = d_url;
download_.push(d_url);
}
}
}
}
main();
let i = 0;
interval = setInterval(() => {
if (i < download_.length) {
document.getElementById(download_[i]).click();
i ++ ;
} else {
clearInterval(interval);
}
}, 500);