简述 我是个喜欢看漫画的人,但是又很贫穷,大部分漫画APP看着看着就要收费了,然后就只能打开浏览器去百度搜来看,比如我常看的‘古风漫画网’;虽然有些时候更新的稍微慢一些,但至少有的看,还是免费。可是又有一些问题。
- 广告特别烦,很多时候点击屏幕跳转下一页就会跳到广告,超级烦啊!!!
- 然后就是一个页面只能看一张图,这就更烦了,要是和app一样一页到底多好。
工具
- request发起请求,获取页面数据;
- cheerio将获取的页面数据(String)转换为可像jQuery一样操作;
- iconv-lite处理一些返回的页面数据乱码;
- 最最最关键的 phantom 爬取漫画图片链接数据;
PhantomJS是一个无头Web浏览器,可以用JavaScript编写脚本。 我简单的理解是:一个没有可视化界面的浏览器,他和普通浏览器一样能打开一个链接加载页面,只是页面你看不到,但是可以用js来操作。爬取思路 观察了几个我自己常看几个漫画网站;
漫画数据不是通过接口返回的;将某一话的漫画链接在phantomJs中打开,用evaluate执行该漫画网站能获取到剩余图片数据的函数,然后将数据存到数据库中;
漫画数据也不是一开始就跟着页面数据返回的;
他自己有js函数能获取该章节所有的图片数据;
梳理流程 漫画网站信息(古风漫画网为例)
- 需要添加为爬取对象的漫画网站的信息
- 网址 path(https://www.gufengmh8.com)
- 是否支持搜索 searchable(支持)
- 章节排序方式 listSort(升序)
- 编码 encoding(UTF-8)
- 搜索地址 searchPath(/search/)
- 搜索关键字 keywords(keywords)
- 搜索结果执行函数 resultCodeJs(作为string类型存到数据库,用eval()执行)
//resultData固定存放数据
/*
将搜索结果中所有漫画数据存起来
name 漫画名称
link 漫画详情链接
img 漫画封面图
*/
$('#contList li').each(function(){
const data = https://www.it610.com/article/{
name: $(this).find('.cover').attr('title'),
link: $(this).find('.cover').attr('href'),
img: $(this).find('img').attr('src')
};
resultData.list.push(data);
})
- 章节结果执行函数 listCodeJs
/*
获取漫画详情中所有漫画章节
title 章节名称
link 章节详情链接
*/
$('#chapter-list-1 li').each(function(){
const data=https://www.it610.com/article/{
title: $(this).text().trim(),
link: $(this).find('a').attr('href')
};
resultData.push(data);
})
- 图片数据执行函数 getImgInfo(用phantomJs打开后执行)
var resultData = https://www.it610.com/article/{
pages: SinMH.getChapterImageCount(),
list: []
};
for(var i=1;
i<=resultData.pages;
i++){
resultData.list.push(SinMH.getChapterImage(i));
}
搜索漫画(百炼成神为例)
/*
web就是事先存储的漫画网站信息JSON数据
keywords: 前台传的搜索关键字
将完整搜索地址拼接起来,大概是这样(https://www.gufengmh8.com/search/?keywords=百炼成神)
用request请求该地址,返回整个搜索结果页面数据(可自行按 F12 看)
然后用cheerio来转换成类似jQuery的操作,eval()函数执行搜索结果执行函数
*/
let resultData = https://www.it610.com/article/{
list: []
};
let rq = new Promise((resolve, reject) => {
const url = encodeURI(web.path + web.searchPath + '?' + web.keywords + '=' + keywords);
request.get(url, (err, response, body) => {
if (!err) {
let $ = cheerio.load(body);
eval(web.resultCodeJs);
resolve(resultData);
} else {
reject(err);
}
});
});
获取漫画所有章节
/*
encoding: null body则返回为Buffer,用iconv转码
*/
request.get({url: 漫画详情的地址, encoding: null}, (err, response, body) => {
if (!err) {
const content = iconv.decode(body, web.encoding).toString();
let $ = cheerio.load(content);
let resultData = https://www.it610.com/article/[];
eval(web.listCodeJs);
......
}
});
phantomJs获取漫画图片数据
const phantom = require('phantom');
let sitepage = null;
//创建网页对象实例
let phInstance = null;
//创建phantomJs实例对象phantom.create()
.then(instance => {
phInstance = instance;
return instance.createPage();
})
.then(page => {
sitepage = page;
return page.open(漫画章节链接地址);
})
.then(status => {
if (status === 'success') {
const jsCode = 'sitepage.evaluate(function(){'+web.getImgInfo+'return resultData;
})';
const resultData = https://www.it610.com/article/eval(jsCode);
return Promise.resolve(resultData);
}
return Promise.reject('Phantom打开url失败');
})
展示 【NodeJs|request+cheerio+iconv-lite+phantomJs制作简单漫画网站爬虫NodeJs项目】页面确实丑,毕竟没有设计师的能力(┬_┬),但是功能是OK的;
文章图片
推荐阅读
- Node.js时间戳和日期互相转换
- nodejs|package.json.lock 文件
- websocket|android中如何使用websocket,以及用nodejs做后台的实例
- javascript|使用vue实现自己音乐播放器仿网易云 移动端 (audio、播放、暂停、上一首、下一首、展示评论、音量控制、进度条拖拽)
- javascript|TODO-4(nodejs 实现一部漫画爬取)
- Nodejs使用前准备,基本使用、常用命令
- Node.js中相同模块是否会被加载多次()
- NodeJS使用lodash去重排序
- nodejs(五)node引入核心模块fs
- nodejs|windows 10系统nodejs安装ffi模块