身为程序员,最喜欢搞“机”了!最近玩了会公众号,但是又懒得写文章。此外,每天都去网上扒拉各种学习资源,所以就想了一个懒人操作——使用爬虫每天获取数据,并自动将数据发送到公众号推文!这样我就可以躺着学习了,hiahiahia!
本文章的基本流程如下图所示。
npm install request --save
npm install request-promise
npm install cheerio --save
npm install iconv-lite --save
{
"permissions": {
"openapi": [
]
},
"triggers":[
{
"name":"scrap",
"type":"timer",
"config":"0 0 5 * * * *"
}
]
}
完成基本的配置以后,就可以开始进一步分析了!
进入资源网站以后,发现其url随页数改变而改变。其中第三页的url如下图所示。
共有96页,最后一页只有7条数据。即共有95*16+7=1527条数据。
这样就可以将相关资源的url全部提取出来,如下图所示。
这里不再赘述详细过程,(本地vscode运行)获取所有url的源码如下:
const request = require('request');//
const iconv = require('iconv-lite');//设置编码格式
const Cheerio = require('cheerio');
var fs = require('fs')
var logger = fs.createWriteStream('ans.txt', {
flags: 'a' // 'a' means appending (old data will be preserved)
})
const requestPromise = (url) =>{
return new Promise((resolve, reject) =>{
//先取消原有的编码格式
request(url, {encoding:null},function (error, response, body) {
if(response.statusCode == 200){
//如果原网页编码格式有问题,可以转成ubt8格式的,该括号内utf-8为原网页编码格式(演示使用)
const bufs = iconv.decode(body, 'utf-8');
const html = bufs.toString('utf-8');//转成utf-8
// console.log(html);
resolve(html);
}
else{
reject(error);
}
});
})
}
const url = 'https://www.ahhhhfs.com/welfare/recourse/page/'; //
for(let i=1;i<=96;i++){
requestPromise(url+i).then(res => {
var $ = Cheerio.load(res);//成功后用cheerio加载
var nodes = $(".entry-media")
for(let j=0;j<nodes.length;j++){
logger.write(nodes[''+j].children[0].children[0].attribs.href+"\n")
}
});
console.log("第"+i+"页finished!")
}
爬取结果
共获取1527个url。
然后将这些url导入云开发数据库,以便日后每天爬一条具体的数据。
首先从云数据库获取今天要爬取的url,爬取数据的代码变化不大,主要就是添加了一个dfs的获取数据算法,将网页中的相关文本消息全部爬下来,云函数爬数据相关代码如下。
function dfs(node){
if(node=='undefined'){
return ""
}
if(node.type=='text'){
return node.data+"\n"
}
if(node.name=='a'&&node.attribs.href[0]!='#'){
return node.attribs.href+"\n"
}
var str = ""
//获取所有孩子节点
var nodes=node.childNodes
for(let i=0;i<nodes.length;i++){
let s = dfs(nodes[i])
if(s!='undefined'){
str+=s
}
}
return str
}
//main函数中
//封装成函数
const requestPromise = (url) =>{
return new Promise((resolve, reject) =>{
//先取消原有的编码格式
request(url, {encoding:null},function (error, response, body) {
if(response.statusCode == 200){
//如果原网页编码格式有问题,可以转成ubt8格式的,该括号内utf-8为原网页编码格式(演示使用)
const bufs = iconv.decode(body, 'utf-8');
const html = bufs.toString('utf-8');//转成utf-8
// console.log(html);
resolve(html);
}
else{
reject(error);
}
});
})
}
requestPromise(url).then(res => {
var $ = Cheerio.load(res);//成功后用cheerio加载
var title = $('h1').text()
var node = $('article .entry-content')['0']
var content = dfs(node)
console.log(title,content)
})
这个算是有点小难搞,毕竟和qi鹅打交道,或多或少都会遇到小坑。
// 获取公众号access_token方法
async function getWechatAccessToken() {
let token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=yourAppid&secret=yourSecret'
const req = options =>
new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) {
reject(error);
}
resolve(response);
});
});
const result = await req({
url: token_url,
method: 'GET'
});
return (typeof result.body === 'object') ? result.body : JSON.parse(result.body);;
}
注意:获取token需要固定云函数的公网ip、延长云函数的超时时间、增加云函数的内存配置,最后在微信公众平台对该ip进行开放。
let article = {
"title":title,
"author":"热爱分享的熊猫",
"digest":'每日资源分享!',
"content":content,
"thumb_media_id":"Ri625hhtBcw-gVmK_XXa8OsW6A8mDluyqZ3SqMcZ2UmW-S1_AOeNG_R5F13DGV2s",//文章封面,需要通过postman获取
"need_open_comment":0,
"only_fans_can_comment":0
}
let token = await getWechatAccessToken()
const addDraft = 'https://api.weixin.qq.com/cgi-bin/draft/add?access_token='+token.access_token
//添加草稿
rp({
method: 'POST',
url: addDraft,
json: true,
form: JSON.stringify({
"articles": [article]
}),
headers: {
"content-type": "application/json",
// "content-Type": "application/x-www-form-urlencoded",
// 'User-Agent': 'Request-Promise'
// "token": event.token
},
})
.then(function(res){
console.log(res)
}).catch(err=>{
console.log(err)
})
你觉得这篇文章有用吗?请投个票吧~
javascript爬虫
资源网站
cheerio中文文档
微信官方文档
js读写文件