背景:針對一些想換頭像的玩家,而又不知道用什么頭像的,作為一名代碼愛好者,能用程序解決的,就不用程序來換頭像,說干就干,然后就整理了一下。
效果圖
環境配置
- 安裝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 || '1'; 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: 400, 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: 200, 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(8081, 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 == 200) { 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="200" height="200"/></a>` }).join('') }).join('') }) } })
總結
寫到這里基本是結束了,對於node我還是懷着一個敬畏的心,摸摸索索終於把這個demo寫完了,項目也傳到gitHub了如有需要可私信