我是个喜欢看漫画的人,但是又很贫穷,大部分漫画APP看着看着就要收费了,然后就只能打开浏览器去百度搜来看,比如我常看的‘古风漫画网’;虽然有些时候更新的稍微慢一些,但至少有的看,还是免费。可是又有一些问题。
正好知道了有 uni-app 这个东西。简单来说,这个uni-app可用vue写页面,然后能打包生成APP(DCloud的团队也太棒了把?)。不过这里主要不是说这个,我要说的是我的服务器项目。
PhantomJS是一个无头Web浏览器,可以用JavaScript编写脚本。
我简单的理解是:一个没有可视化界面的浏览器,他和普通浏览器一样能打开一个链接加载页面,只是页面你看不到,但是可以用js来操作。
观察了几个我自己常看几个漫画网站;
漫画数据不是通过接口返回的;
漫画数据也不是一开始就跟着页面数据返回的;
他自己有js函数能获取该章节所有的图片数据;
将某一话的漫画链接在phantomJs中打开,用evaluate执行该漫画网站能获取到剩余图片数据的函数,然后将数据存到数据库中;
//resultData固定存放数据
/*
将搜索结果中所有漫画数据存起来
name 漫画名称
link 漫画详情链接
img 漫画封面图
*/
$('#contList li').each(function(){
const data = {
name: $(this).find('.cover').attr('title'),
link: $(this).find('.cover').attr('href'),
img: $(this).find('img').attr('src')
};
resultData.list.push(data);
})
/*
获取漫画详情中所有漫画章节
title 章节名称
link 章节详情链接
*/
$('#chapter-list-1 li').each(function(){
const data={
title: $(this).text().trim(),
link: $(this).find('a').attr('href')
};
resultData.push(data);
})
var resultData = {
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 = {
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 = [];
eval(web.listCodeJs);
......
}
});
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 = eval(jsCode);
return Promise.resolve(resultData);
}
return Promise.reject('Phantom打开url失败');
})