微信不提供公众号分组管理,部分公众号内容优质但更新频率低,我们通过抓取特定公众号更新解决这个问题。
网上介绍的方法较多,参考各位大神的文章后,最后选择了通过公众号管理平台抓取的方法。
大体思路:
- 通过公众号管理平台对文章名称、更新时间、文章链接等信息进行抓取;
- 结果存入mysql数据库备用;
- 读取mysql数据生成html,通过flask提供web服务供局域网内浏览器使用。
其中,参数中的 cookie、token 需在抓取前手动更新;fakeid 需手工获取一次即可。
步骤如下:
1准备:
注册公众号,以登录公众号平台 mp.weixin.qq.com。
2 mysql 中建两个表
表1: accountlist,用于存储待抓取公众号的名称和fakeid:
-
nickname:公众号名称
-
fakeid:公众号 fakeid
表2:wechat_article,用于存储抓取公众号得到的信息,包括
- title:公众号的文章名
- nickname: 公众号名称
- update_time:文章的更新时间
- link: 文章链接
- fakeid:公众号fakeid
3 抓取文章并存储
代码如下:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# '''
# @File : test.py
# @Time : 2022/03/24
# @Author : 疾风jf
# '''
#
import pymysql
from dbutils.pooled_db import PooledDB
import time
import requests
import random
POOL = PooledDB(
creator=pymysql,
host='127.0.0.1',
port=3306,
user='root',
password= yourpassword, # 输入数据库密码
database='testdb', # 数据库名
charset='utf8'
)
# 毫秒转化为日期
def getDate(times):
timearr = time.localtime(times)
date = time.strftime("%Y-%m-%d %H:%M:%S", timearr)
return date
#读fakeid
def listWeChatFilId():
conn = POOL.connection()
cursor = conn.cursor()
cursor.execute("select fakeid from accountlist") # 从表accountlist读fakeid
result = cursor.fetchall()
cursor.close()
conn.close()
return result
# 爬取的文章存入数据库
def saveWeChatArticle(dict):
conn = POOL.connection()
cursor = conn.cursor()
sql = "insert ignore into wechat_article (`title`, `update_time`, `link`, `fakeid`) values(\"%s\",\"%s\",\"%s\",\"%s\")" % (str(dict[0]), str(dict[1]), str(dict[2]), str(dict[3]))
#sql 是字符串;因此变量s%处,用转义字符 \" 输入双引号,后面,用str 将每个值转为str类型;
cursor.execute(sql)
conn.commit() # 提交到数据库
cursor.close()
conn.close
# 更新数据库的nickname
def updatenickname():
conn = POOL.connection()
cursor = conn.cursor()
sql = """UPDATE wechat_article, wechat_public
SET wechat_article.nickname = accountlist.nickname
WHERE wechat_article.fakeid = accountlist.fakeid
"""
try:
cursor.execute(sql)
conn.commit()
except:
conn.rollback()
cursor.close()
conn.close()
# 爬取文章,并调用函数存入数据库
def listAllArticle(fakeId):
url = "https://mp.weixin.qq.com/cgi-bin/appmsg"
headers = {
"Cookie": "your cookie", #手动更新
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36",
}
data = {
"token": "your token", # 手动更新
"lang": "zh_CN",
"f": "json",
"ajax": "1",
"action": "list_ex",
"begin": "0",
"count": "5",
"query": "",
"fakeid": fakeId, # fakeid 从表 accountlist 里自动获取
"type": "9",
}
for i in range(2):
data["begin"] = i * 5
# 睡3-10秒再爬(随机取)
sleepTime = random.randint(3, 10)
print(sleepTime)
time.sleep(sleepTime)
#爬,返回结果存content_json
content_json = requests.get(url, headers=headers, params=data).json()
#从content_json(dict类型)中提取数据。
for item in content_json["app_msg_list"]:
items = [item["title"], getDate(item["update_time"]), item["link"], ''.join(fakeId)]
print(items)
saveWeChatArticle(items) # 调用 savewechatarticle() 存入数据库
if __name__ == '__main__':
listFakeId = listWeChatFilId() # 取fakeId的值
for i in listFakeId: # 取fakeid,爬取文章信息
listAllArticle(i)
updatenickname() # 更新表中的nickname (公众号名称)
4 注意事项
- 运行时,需登录公众号后台;
- 重新登录后台,cookie 和 token 会变,爬取前需要手动更新;
- 表 accountlist 需手动维护。fakeid 需要手动添加到accountlist,但不用每次更新。
5.生成flask web服务,代码如下:
D:\yourproject
├─app.py
├─templates
│ └─index.html
app.py
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# '''
# @File : app.py
# @Time : 2022/03/24
# @Author : 疾风jf
# '''
# 数据库读取wechat文章,传给flask服务器上index.html
#
import pymysql
from dbutils.pooled_db import PooledDB
from flask import Flask, render_template
from gevent import pywsgi
POOL = PooledDB(
creator=pymysql,
host='127.0.0.1',
port=3306,
user='root',
password= yourpassword, # 输入数据库密码
database='testdb', # 数据库名
charset='utf8'
)
app = Flask(__name__)
@app.route('/')
def index():
conn=POOL.connection()
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql=""" SELECT DISTINCT title,nickname,update_time,link FROM wechat_article
ORDER BY update_time DESC
limit 100
"""
cursor.execute(sql)
result = cursor.fetchall()
cursor.close()
conn.close()
return render_template('index.html',result=result)
if __name__ == '__main__':
server = pywsgi.WSGIServer(('0.0.0.0',5000),app) # host选0.0.0.0,可用局域网ip访问;如果选localhost,就本机访问。
server.serve_forever()
index.htm里乞丐版表格输出,参考如下:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello, world!</title>
<style>
.table11_6 table {
width:100%;
margin:15px 0;
border:0;
}
.table11_6 th {
background-color:#96C7ED;
color:#000000
}
.table11_6,.table11_6 th,.table11_6 td {
font-size:0.95em;
text-align:left;
padding:4px;
border-collapse:collapse;
}
.table11_6 th,.table11_6 td {
border: 1px solid #73b4e7;
border-width:1px 0 1px 0;
border:2px inset #ffffff;
}
.table11_6 tr {
border: 1px solid #ffffff;
}
.table11_6 tr:nth-child(odd){
background-color:#dcecf9;
}
.table11_6 tr:nth-child(even){
background-color:#ffffff;
}
</style>
</head>
<body bgcolor="#fdfcf8">
<h2>Hello, world!</h2>
{% block page_content %}
<table class=table11_6 align="center" width="100%">
<caption>文章列表</caption>
<tr align="center">
<th>title</th>
<th>nickname</th>
<th>update_time</th>
<th>link</th>
</tr>
{% for item in result %}
<tr>
<td><a href=" {{ item['link'] }} " target="_blank"> {{ item['title'] }} </a> </td>
<td>{{ item['nickname'] }}</td>
<td>{{ item['update_time'] }}</td>
<td><a href=" {{ item['link'] }} ">link</a></td>
</tr>
{% endfor %}
</table>
{% endblock %}
<br>
<br>
<br>
</body>
</html>
6,运行app.py后, 浏览器打开http://your_local_ip:5000, 应能访问。
效果图:
7 批处理
也可直接用批处理运行app.py,
新建app.bat
@echo off
cd D:\yourproject\
python app.py