node爬虫之图片下载
背景:针对一些想换头像的玩家,而又不知道用什么头像的,作为一名代码爱好者,能用程序解决的,就不用程序来换头像,说干就干,然后就整理了一下。
效果图
环境配置
- 安装node环境
- node -v
- node版本最好在8.11.1以上
项目结构
assets是存放所下载的图片
static是静态资源页面
eg.js是下载图片示例(node eg.js)
img.json是网页所获取的json数据
index.js属于服务端
安装依赖
npm init ( 会生成一个package.json) npm i express --save-dev npm i cheerio--save-dev npm i superagent--save-dev npm i superagent-charset--save-dev npm i request--save-dev
- SuperAgent 是一个轻量级、灵活的、易读的、低学习曲线的客户端请求代理模块,使用在NodeJS环境中
- superagent-charset 防止爬取下来的数据乱码,更改字符格式
- cheerio 是jquery核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对DOM进行操作的地方。
- request 的功能比较强大,在 这里只是为了下载图片用的
代码区
1. eg.js
var fs = require('fs');
var request = require("request");
var path = require('path');
var src = "https://pic.qqtn.com/up/2019-6/2019061811092772406.jpg";
var writeStream = fs.createWriteStream('./assets/aa.png');
var readStream = request(src)
readStream.pipe(writeStream); readStream.on('end', function() {
console.log('文件下载成功');
});
readStream.on('error', function() {
console.log("错误信息:" + err)
})
writeStream.on("finish", function() {
console.log("文件写入成功");
writeStream.end();
});
2.index.js
var superagent = require('superagent');
var charset = require('superagent-charset');
charset(superagent);
var express = require('express');
var baseUrl = 'https://www.qqtn.com/';
const cheerio = require('cheerio');
var request = require("request");
var fs = require('fs')
var path = require('path') var checkDir = fs.existsSync("assets");
var app = express();
app.use(express.static('static'))
app.get('/index', function (req, res) {
//设置请求头
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
//类型
console.log(req.query, '类型')
var type = req.query.type;
//页码
var page = req.query.page;
type = type || 'weixin';
page = page || '';
var route = `tx/${type}tx_${page}.html`
//网页页面信息是gb2312,所以chaeset应该为.charset('gb2312'),一般网页则为utf-8,可以直接使用.charset('utf-8')
superagent.get(baseUrl + route)
.charset('gb2312')
.end(function (err, sres) {
var items = [];
if (err) {
console.log('ERR: ' + err);
res.json({ code: , msg: err, sets: items });
return;
}
var $ = cheerio.load(sres.text);
$('div.g-main-bg ul.g-gxlist-imgbox li a').each(function (idx, element) {
var $element = $(element);
var $subElement = $element.find('img');
var thumbImgSrc = $subElement.attr('src');
items.push({
title: $(element).attr('title'),
href: $element.attr('href'),
thumbSrc: thumbImgSrc
});
});
if (!checkDir) {
fs.mkdir('assets', function (error) {
if (error) {
console.log(error);
return false;
}
console.log('创建目录成功');
})
}
fs.access(path.join(__dirname, '/img.json'), fs.constants.F_OK, err => {
if (err) { // 文件不存在
fs.writeFile(path.join(__dirname, '/img.json'), JSON.stringify([
{
route,
items
}
]), err => {
if (err) {
console.log(err)
return false
}
console.log('保存成功')
})
} else {
fs.readFile(path.join(__dirname, '/img.json'), (err, data) => {
if (err) {
return false
}
data = JSON.parse(data.toString())
let exist = data.some((page, index) => {
return page.route == route
})
if (!exist) {
fs.writeFile(path.join(__dirname, 'img.json'), JSON.stringify([
...data,
{
route,
items
},
]), err => {
if (err) {
return false
}
})
}
})
}
res.json({ code: , msg: "", data: items });
})
try {
fs.readFile(path.join(__dirname, '/img.json'), (err, data) => {
if (err) {
return false
}else{
data = JSON.parse(data.toString());
data.map((v, i) => {
v.items.map((v,i) => {
i = request(v.thumbSrc)
// 后缀.jpg可用正则匹配
i.pipe(fs.createWriteStream('./assets/' + v.title + '.jpg'));
}) })
}
})
} catch(err){}
})
});
app.get('/show', (req, res) => {
fs.readFile(path.join(__dirname, 'img.json'), (err, data) => {
if (err) {
console.log(err)
return false
}
res.json(data.toString())
})
})
var server = app.listen(, function () {
var host = server.address().address
var port = server.address().port
})
3.static文件夹下index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
4.static文件夹下index.js
fetch('/index', {
method: 'GET'
}).then(res => {
return res.json()
}).then(res => { if (res.code == ) {
fetch('/show', {
method: 'GET'
}).then(res => {
return res.json()
}).then(res => {
res = JSON.parse(res)
console.log(res, res.length)
document.body.innerHTML = res.map((page, index) => {
console.log(page)
return page.items.map((item, itemIndex) => {
return `<a href="${item.thumbSrc}" ><img src="${item.thumbSrc}" width="" height=""/></a>`
}).join('')
}).join('')
})
} })
总结
写到这里基本是结束了,对于node我还是怀着一个敬畏的心,摸摸索索终于把这个demo写完了,项目也传到gitHub了如有需要可私信
node爬虫之图片下载的更多相关文章
- Node.js制作图片下载爬虫的一般步骤
图片下载爬虫分两部分:爬页面和下载图片. 爬页面时先看网址是https还是http的,然后选择不同的内置对象: 其次看编码,如果是charset=gb2312的网页就需要iconv帮忙转码,好在大部分 ...
- node爬虫 -- 网页图片
相信大家都听说过爬虫,我们也听说过Python是可以很方便地爬取网络上的图片,但是奈何本人不会Python,就只有通过 Node 来实践一下了. 接下来看我如何 板砖 ! !!
- Node.js mimimn图片批量下载爬虫 1.00
这个爬虫在Referer设置上和其它爬虫相比有特殊性.代码: //====================================================== // mimimn图片批 ...
- Node.js meitulu图片批量下载爬虫1.01版
在 http://www.cnblogs.com/xiandedanteng/p/7614051.html 一文我曾经书写过一个图片下载爬虫,但原有程序不是为下载图片而设计故有些绕,于是稍微改写了一下 ...
- node 爬虫 --- 批量下载图片
步骤一:创建项目 npm init 步骤二:安装 request,cheerio,async 三个模块 request 用于请求地址和快速下载图片流. https://github.com/reque ...
- python简易爬虫来实现自动图片下载
菜鸟新人刚刚入住博客园,先发个之前写的简易爬虫的实现吧,水平有限请轻喷. 估计利用python实现爬虫的程序网上已经有太多了,不过新人用来练手学习python确实是个不错的选择.本人借鉴网上的部分实现 ...
- (8)分布式下的爬虫Scrapy应该如何做-图片下载(源码放送)
转载主注明出处:http://www.cnblogs.com/codefish/p/4968260.html 在爬虫中,我们遇到比较多需求就是文件下载以及图片下载,在其它的语言或者框架中,我们可能 ...
- 第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器
第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器 编写spiders爬虫文件循环 ...
- 手把手教你写基于C++ Winsock的图片下载的网络爬虫
手把手教你写基于C++ Winsock的图片下载的网络爬虫 先来说一下主要的技术点: 1. 输入起始网址,使用ssacnf函数解析出主机号和路径(仅处理http协议网址) 2. 使用socket套接字 ...
随机推荐
- Servlet一次乱码排查后的总结
由来 在写一个小小的表单提交功能的时候,出现了乱码,很奇怪request上来的参数全部是乱码,而从数据库查询出来的中文显示到页面正常,锁定肯定是request对象那里出了问题.后来经过排查,发现是我封 ...
- ELK 安装
ELK 是 Elasticesarch Logstash kibana 三个开源软件 Elasticsearch是个开源分布式搜索引擎,提供搜集.分析.存储数据三大功能.它的特点有:分布式,零配置, ...
- ASP.NET CORE HOW TO ADD "ACCESS-CONTROL-EXPOSE-HEADERS" HEADERS?
services.AddCors(options => { options.AddPolicy("AnotherPolicy" ...
- Paper | LISTEN, ATTEND AND SPELL: A NEURAL NETWORK FOR LARGE VOCABULARY CONVERSATIONAL SPEECH RECOGNITION
目录 1. 相关工作 2. 方法细节 2.1 收听器 2.2 注意力和拼写 本文提出了一个基于神经网络的语音识别系统List, Attend and Spell(LAS),能够将语音直接转录为文字. ...
- 第四组项目总结(UML图设计)
第四组项目总结(UML图设计) 相关链接: 墨刀原型链接:https://pan.baidu.com/s/1qrVI_je8NONVHT_FwH6Pwg 需求文档链接:https://www.cnbl ...
- webpack入门配置步骤详解
1.初始化 1.npm install webpack webpack-cli webpack-dev-server --g 全局安装必要的第三方插件 2.mkdir config dist src ...
- app——升级测试点
APP版本升级的测试点 该文章转载于:https://www.cnblogs.com/changpuyi/p/8618755.html 移动端版本更新升级是一个比较重要的功能点,主要分为强制更新和 ...
- CentOS 7 firewalld详解,添加删除策略
一.CentOS7中firewall防火墙 修改防火墙配置文件之前,需要对之前防火墙[/etc/firewalld/zones/public.xml]做好备份 重启防火墙后,需要确认防火墙状态和防火墙 ...
- Java入门系列之字符串特性(二)
前言 上一节我们讲解到字符串本质上就是字符数组,同时详细讲解了字符串判断相等需要注意的地方,本节我们来深入探讨字符串特性,下面我们一起来看看. 不可变性 我们依然借助初始化字符串的方式来探讨字符串的不 ...
- docker安装完报错:Failed to start docker.service: Unit docker.service is masked
执行 systemctl start docker 报错 Failed to start docker.service: Unit docker.service is masked. 解决 syste ...