
开篇寄语
这个可以定制规则的爬虫系统,隶属于伯衡君正在制作的财富增值攻略系统,整个系统尚未完成,但是这个信息聚合的爬虫系统基本完成了,可以公开一些核心代码,能够给一些需要的人启发来自制。本站之前也分享了不少相关爬虫内容,具体可以参看下方的前情提要,也受到了很多启发,详情内容,请看本篇文章。
前情提要
- 《来和伯衡君一起快速入门Python爬虫——Beautifulsoup篇(一)》
- 《使用Nodejs爬取图片音频视频与Python相比平分秋色》
- 《使用 Node.js 爬虫后将数据储存到MySQL数据库并生成API调用》
- 《如何结合爬虫技术让你的金融投资更具科学性》
- 《Yealico一款可适用于iPad和iPhone上看18禁视频和漫画的应用》
包含技术
- HTML + CSS + JavaScript + Node.js + Mysql
- 其中,Node.js 需要使用的依赖包括:async、request、cheerio、utf8、mysql、iconv-lite(这个主要是解决非 utf-8 格式的网站爬取乱码问题)
内容详情
这个信息爬虫,伯衡君主要是用来辅助进行全球投资的,而伯衡君设计的财富增值攻略系统的宗旨——赚更多钱,花更少钱,从而达成财富最大程度增值,这里面的信息作用非常重要。
有效的信息可以帮助你更加科学投资,从而提高投资胜率,而花更少的钱则是需要信息带给你各种优惠信息,所以可见有效信息在个人财富增值上的妙用。
先来简单介绍一下这个爬虫系统的主要功能:

目前,伯衡君将我感兴趣的新闻内容,按照类别分成了综合、财经、科技、观点、娱乐、影音、福利、学习和各国政府公告,而喜爱则是勾选感兴趣的文章后添加到的地方,类似于稍后即可。
如何想看某篇文章,可以点开后,直接前往对应具体网页查看详情。
而其中的黑名单,主要是屏蔽一些不感兴趣含有某些关键词的文章,如下所示:

而爬取规则,则主要是受到一款漫画应用的影响,在前情提要中有写,名字叫做 Yealico,它就是通过对一些网站制定爬取规则,可以观看漫画和视频,有兴趣的朋友可以下载试试。
爬虫规则设置页面详情如下:

有的信息源是采用的 Api 模式,有的是直接通过网站 DOM 爬取,有的则是通过 RSS 形式,因为 RSS 形式,伯衡君可以通过 inoreader 应用订阅获取,所以就没有编列规则在内。
有关 inoreader 相关内容,可以参看以下文章:
- 《RSS订阅器inoreader一些使用心得(一)》
- 《RSS订阅器inoreader一些使用心得(二)》
- 《RSS订阅器inoreader一些使用心得(三)》
- 《结合播客专业搜索引擎ListenNotes让Inoreader化身播客播放器,任性听听听》
在爬虫获取的过程中,某些网站可能失效了,需要检测它的有效性,这个要注意,而有的网站没有失效,有可能因为改版,制定的规则失效了,所以也需要列出来爬取的内容条数,如果爬取条数显示是 0 的话,那就说明该网站改版了,需要从新制定规则。
规则模式一、二、三、四和五,是应对爬取内容的标题和内容所表现出来的差异而设计的,api 模式返回内容各不相同,这个需要单独对应,而四是指 <a></a> 标签中链接不带 https 这样开头的,而五则是 <a></a> 标签中链接带 https 这样开头的。
核心代码如下:
//提供寰宇新闻专区新闻采集信息 app.get('/api/globalNewsData', (req, res) => { var selectArr = [];//最新新闻集合 var requests = []; var blackLists = [];//黑名单集合 var favorLists = [];//收藏新闻集合 var totalsLists = {};//爬取数量集合 con.query(`SELECT * FROM editRulesTable WHERE action = 1 AND catalogue = ${req.query.catalogue}; SELECT * FROM blackListWords WHERE id = 1; SELECT * FROM globalNewsTable ORDER BY stars;`, function (err, result, fields) { let resLength = result[0].length; let newsLength = result[2].length; for (let i = 0; i < resLength; i++) { requests.push({ url: result[0][i].rulesname, method: 'GET', headers: { 'Content-Type': 'text/html; charset=UTF-8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36' } }); } masync.map(requests,function (obj, callback) { request(obj, function (error, response, body) { if (!error && response.statusCode == 200) { try{ if (body.trim()[0] == '<') { body = body } else { body = JSON.parse(body); } }catch(err){ console.info(obj.url); } con.query(`UPDATE editRulesTable SET valid = 0 WHERE rulesname = '${obj.url}'`, function (err, result, fields) {}); callback(null, body); } else { con.query(`UPDATE editRulesTable SET valid = 1, action = 0 WHERE rulesname = '${obj.url}'`, function (err, result, fields) {}); callback(error || response.statusCode); } }); }, function (err, results) { if (err) { console.log(err) } else { for (var i = 0; i < results.length; i++) { if (result[0][i].classmodel == 3) { try{ for (let a of results[i].data.cards[0].card_group) { selectArr.push({ title: `【${result[0][i].webname}】${a.desc.trim()}`, url: `${a.scheme}` }) } }catch(errors){ selectArr.push({ title: "【微博 api 出现问题,请检查地址以及配置规则】", url: "#" }) } } else if (result[0][i].classmodel == 1) { try{ for (let a of results[i].data) { selectArr.push({ title: `【${result[0][i].webname}】${a.target.title.trim()}`, url: `${`https://www.zhihu.com/question/` + a.target.id}` }) } }catch(errors){ selectArr.push({ title: "【知乎 api 出现问题,请检查地址以及配置规则】", url: "#" }) } } else if (result[0][i].classmodel == 2) { try{ for (let a of results[i].data.list) { selectArr.push({ title: `【${result[0][i].webname}】${a.title.trim()}`, url: `${a.url}` }) } }catch(errors){ selectArr.push({ title: "【腾讯新闻 api 出现问题,请检查地址以及配置规则】", url: "#" }) } } else if (result[0][i].classmodel == 4) { const $ = cheerio.load(results[i]); let splitArr = result[0][i].content.split(','); for (let j = 0; j < splitArr.length; j++) { $(`${splitArr[j]}`).each(function () { if (result[0][i].rulesname == 'https://www.yicai.com/') { try{ let keys = `${$(this).find('h2').text().match(/[\u4e00-\u9fa5]/gi) == null ? $(this).find('h2').text() : $(this).find('h2').text().trim()}`; selectArr.push({ title: `【${result[0][i].webname}】` + keys, url: 'https://www.yicai.com' + `${$(this).attr('href')}` }); }catch(errors){ selectArr.push({ title: `【${result[0][i].webname} 出现问题,请检查地址以及配置规则】`, url: "#" }); } } else if (result[0][i].rulesname == 'https://business.sohu.com/') { try{ let keys = `${$(this).text().match(/[\u4e00-\u9fa5]/gi) == null ? $(this).text() : $(this).text().trim()}`; selectArr.push({ title: `【${result[0][i].webname}】` + keys, url: $(this).attr('href').indexOf('https') > -1 ? `${$(this).attr('href')}` : `https://www.sohu.com${$(this).attr('href')}` }); }catch(errors){ selectArr.push({ title: `【${result[0][i].webname} 出现问题,请检查地址以及配置规则】`, url: "#" }); } }else if(result[0][i].rulesname == 'https://369369.xyz/host/'){ try{ let keys = `${$(this).text().match(/[\u4e00-\u9fa5]/gi) == null ? $(this).text() : $(this).text().trim()}`; selectArr.push({ title: `【${result[0][i].webname}】` + keys, url: `https://369369.xyz/host/${$(this).attr('href')}`}); }catch(errors){ selectArr.push({ title: `【${result[0][i].webname} 出现问题,请检查地址以及配置规则】`, url: "#" }); } }else { try{ let paramName = `${$(this).attr('href')}`.indexOf('/') == 0 ? `${$(this).attr('href')}` : `/${$(this).attr('href')}`; let keys = `${$(this).text().match(/[\u4e00-\u9fa5]/gi) == null ? $(this).text() : $(this).text().trim()}`; selectArr.push({ title: `【${result[0][i].webname}】` + keys, url: new URL(result[0][i].rulesname).origin + paramName }); }catch(errors){ selectArr.push({ title: `【${result[0][i].webname} 出现问题,请检查地址以及配置规则】`, url: "#" }); } } }); } } else if (result[0][i].classmodel == 5) { const $ = cheerio.load(results[i]); let splitArr = result[0][i].content.split(','); for (let j = 0; j < splitArr.length; j++) { try{ $(`${splitArr[j]}`).each(function () { selectArr.push({ title: `【${result[0][i].webname}】` + `${$(this).text().match(/[\u4e00-\u9fa5]/gi) == null ? $(this).text() : $(this).text().trim() }`, url: `${$(this).attr('href')}` }) }); }catch(errors){ selectArr.push({ title: `【${result[0][i].webname} 出现问题,请检查地址以及配置规则】`, url: "#" }); } } } } } [...selectArr].map(x=>x.title.split('】')[0].slice(1)).forEach(function (x) { totalsLists[x] = (totalsLists[x] || 0) + 1; }); let crawlTotalsKeys = Object.keys(totalsLists); let crawlTotalsVals = Object.values(totalsLists); for(let t = 0; t<crawlTotalsKeys.length; t++){ con.query(`UPDATE editRulesTable SET totals = ${crawlTotalsVals[t]} WHERE webname = '${crawlTotalsKeys[t]}'`, function (err, result, fields) {}); } const regex = new RegExp(`${result[1][0].title}`, 'g'); selectArr = selectArr.sort((x, y) => x.title.length - y.title.length).filter(x => x.title.indexOf(`${req.query.yesfilter}`) > -1).filter((item, y) => !item.title.match(regex)); selectArr = selectArr.filter(function (value, index) { return selectArr.map(x => x.title).indexOf(value.title) == index }); //筛选出在收藏中文章 for (let i = 0; i < newsLength; i++) { favorLists.push(result[2][i].title); } selectArr = selectArr.filter(x => favorLists.indexOf(x.title) == -1 && x.title.length >= 1); res.end(JSON.stringify([{ 'ret': true, 'code': selectArr }]), 'utf-8'); }); }); });
不是很难,感兴趣的朋友可以依此自行自制,依靠有效的信息,可以提高投资的胜率,同时,也能通过及时的信息,节省开支。
- 我的微信
- 微信扫一扫加好友
-
- 我的微信公众号
- 扫描关注公众号
-