背景:针对一些想换头像的玩家,而又不知道用什么头像的,作为一名代码爱好者,能用程序解决的,就不用程序来换头像,说干就干,然后就整理了一下。

效果图

环境配置

  • 安装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

代码区

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爬虫之图片下载的更多相关文章

  1. Node.js制作图片下载爬虫的一般步骤

    图片下载爬虫分两部分:爬页面和下载图片. 爬页面时先看网址是https还是http的,然后选择不同的内置对象: 其次看编码,如果是charset=gb2312的网页就需要iconv帮忙转码,好在大部分 ...

  2. node爬虫 -- 网页图片

    相信大家都听说过爬虫,我们也听说过Python是可以很方便地爬取网络上的图片,但是奈何本人不会Python,就只有通过 Node 来实践一下了.   接下来看我如何 板砖 ! !!   

  3. Node.js mimimn图片批量下载爬虫 1.00

    这个爬虫在Referer设置上和其它爬虫相比有特殊性.代码: //====================================================== // mimimn图片批 ...

  4. Node.js meitulu图片批量下载爬虫1.01版

    在 http://www.cnblogs.com/xiandedanteng/p/7614051.html 一文我曾经书写过一个图片下载爬虫,但原有程序不是为下载图片而设计故有些绕,于是稍微改写了一下 ...

  5. node 爬虫 --- 批量下载图片

    步骤一:创建项目 npm init 步骤二:安装 request,cheerio,async 三个模块 request 用于请求地址和快速下载图片流. https://github.com/reque ...

  6. python简易爬虫来实现自动图片下载

    菜鸟新人刚刚入住博客园,先发个之前写的简易爬虫的实现吧,水平有限请轻喷. 估计利用python实现爬虫的程序网上已经有太多了,不过新人用来练手学习python确实是个不错的选择.本人借鉴网上的部分实现 ...

  7. (8)分布式下的爬虫Scrapy应该如何做-图片下载(源码放送)

      转载主注明出处:http://www.cnblogs.com/codefish/p/4968260.html 在爬虫中,我们遇到比较多需求就是文件下载以及图片下载,在其它的语言或者框架中,我们可能 ...

  8. 第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器

    第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器 编写spiders爬虫文件循环 ...

  9. 手把手教你写基于C++ Winsock的图片下载的网络爬虫

    手把手教你写基于C++ Winsock的图片下载的网络爬虫 先来说一下主要的技术点: 1. 输入起始网址,使用ssacnf函数解析出主机号和路径(仅处理http协议网址) 2. 使用socket套接字 ...

随机推荐

  1. 洛谷 SP14932 LCA - Lowest Common Ancestor

    洛谷 SP14932 LCA - Lowest Common Ancestor 洛谷评测传送门 题目描述 A tree is an undirected graph in which any two ...

  2. 小程序-小菊花loading

    界面----交互 wx.showLoading() 显示loading提示框.需主动调用wx.hideLoading()才能关闭提示框 参数: 属性 类型 默认值 必填 说明 title string ...

  3. MySQL select from where multiple conditions

    Maybe one of the most used MySQL commands is SELECT, that is the way to stract the information from ...

  4. 还在担心网聊相亲的小姐姐,美女变恐龙!Python帮你"潜伏"侦查

    ​ 最近,小编的一个朋友很是苦恼,他在Python交流的群里,认识了一个妹子,看头像感觉挺不错的,大家都喜欢摄影,蛮谈得来的!但是想要约见面却不敢,因为他看过<头号玩家>,深知躲在电脑背后 ...

  5. 手动创建分区以及软硬raid的问题

    本文章旨在介绍安装centos7时手动分区问题,及其所对应的软硬raid问题.在新建centos7系统时,需要手动分区时,提供给我们三个选项: 在上图中,默认选项为“Standard Partitio ...

  6. 【OCR技术系列之二】文字定位于切割

    要做文字识别,第一步要考虑的就是怎么将每一个字符从图片中切割下来,然后才可以送入我们设计好的模型进行字符识别.现在就以下面这张图片为例,说一说最一般的字符切割的步骤是哪些. 当然,我们实际上要识别的图 ...

  7. Python 十大装 X 语法(二)

    Python 是一种代表简单思想的语言,其语法相对简单,很容易上手.不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了.本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并 ...

  8. PELT算法

    参考:http://www.wowotech.net/process_management/PELT.html 本文是对https://lwn.net/Articles/531853/的翻译 mark ...

  9. pandas 学习 第5篇:DataFrame - 访问数据框

    数据框是用于存储数据的二维结构,分为行和列,一行和一列的交叉位置是一个cell,该cell的位置是由行索引和列索引共同确定的.可以通过at/iat,或loc/iloc属性来访问数据框的元素,该属性后跟 ...

  10. CSV文件数据如何读取、导入、导出到新的CSV文件中以及CSV文件的创建

    CSV文件数据如何读取.导入.导出到新的CSV文件中以及CSV文件的创建 一.csv文件的创建 (1)新建一个文本文档: 打开新建文本文档,进行编辑. 注意:关键字与关键字之间用英文半角逗号隔开.第一 ...