Python爬虫爬取微信公众号
Python爬虫爬取微信公众号
参考
目标
获取“海南大学”微信公众号,2021年9月份至今全部推文的链接、时间、点赞数、阅读量、在看数等数据
分析
- 在微信公众平台可以获取推文的url
- 在微信的客户端打开推文可以查看到阅读量、点赞数、在看数这些信息
- 通过抓包的方式来获取这些信息

获取推文链接
在网页中进行抓包
可以通过在微信公众平台创作文章时插入超链接的方式,获得公众号文章的链接信息
-
在插入超链接的界面打开调试界面(F12),在Network中进行抓包
选择其它公众号,搜索海南大学,选择海南大学
- 可以在
\appmsg
中找到推文的信息(在搜索海南大学之前请先点击调式界面左上角的Clear,清理一下不需要的链接)
-
在Headers中可以获得获得链接的URL,Payload中获得链接的参数
Request URL中
?
之前的部分是不带参数的URL,?
之后的是参数
- 在Headers中可以获得cookie
- 在浏览器中打开URL可以看到我们想要的信息,之后可以使用正则表达式提取这些信息
编写爬虫代码
-
设置不使用系统代理,参考博客
1
2
3import os
os.environ['NO_PROXY'] = "mp.weixin.qq.com" -
设置标头
1
2
3
4headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"Cookie": "RK=N9tk1HjFWK; ...太长省略... skey=@ZhnRkc9u3"
} -
设置url和参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15## url
request_url = "https://mp.weixin.qq.com/cgi-bin/appmsg"
## 参数
params = {
'action': 'list_ex',
'begin': 5*page_num, ## 起始项,page_num是页数
'count': '5', ## 一页有5项内容
'fakeid': 'MzIwMzUxNjgzNw==', ## 公众号的唯一标识
'type': '9',
'query': '',
'token': '773287030',
'lang': 'en_US',
'f': 'json',
'ajax': '1',
} -
使用Get请求获取url源码
1
2
3import requests
resp = requests.get(request_url, params=params, headers=headers) -
编写正则表达式,用于提取
create_time
、link
、title
可以先在regex101上面验证正则表达式是否正确
1
2
3
4
5
6
7
8
9
10
11
12
13import re
## 预加载正则表达式
reg_exp = re.compile(r'"create_time":(?P<create_time>\d+).*?"link":"(?P<link>.*?)",.*?"title":"(?P<title>.*?)"', re.S)
## 使用finditer在resp中进行查找,finditer返回一个可迭代对象
itr = reg_exp.finditer(resp.text)
## 循环获取迭代器中的内容,每次获取一个match对象,使用["组名"]可以获取对应组的内容
for mch in itr:
print(mch["create_time"])
print(mch["title"])
print(mch["link"]) -
将int型时间转换成标准时间,参考博客
1
2
3
4
5
6from datetime import datetime
create_time = mch.group("create_time")
## 1658971570 <class 'str'>
create_date = datetime.fromtimestamp(int(create_time))
## 2022-07-28 09:26:10 <class 'datetime.datetime'> -
将获取的信息写入csv文件
newline=''
换行将不会空行,参考博客utf-8-sig
编码,使用excel打开中文不会乱码,参考博客1
2
3
4
5
6
7
8
9
10import csv
f = open("hainanuniversity.csv", mode="w", encoding='utf-8-sig', newline='')
csvwriter = csv.writer(f)
for mch in itr:
## 安排一行的内容
lst = [mch.group("create_time"), mch.group("title"), mch.group("link")]
## 按行写入
csvwriter.writerow(lst) -
每爬完一页暂停3秒
1
2
3import time
time.sleep(3) -
整个代码要对页数进行循环
1
2for page_num in range(100):
...
完整代码
1 | import requests ## request库 |
获取点赞数和阅读量
点赞数和阅读量这些信息在网页上是没有的,在客户端才可以看见,对客户端的抓包就需要借助一些如Fiddler的抓包工具
Fiddler下载Download Fiddler Classic
微信客户端抓包
在Fiddler中抓取微信客户端公众号推文的信息
- 配置好Fiddler后打开Fiddler
- 打开微信,点开一篇公众号文章

- 然后在Fiddler中找到对应的链接
- 可以在标头中查看cookies和user-agent等信息
编写爬虫代码
-
设置不使用系统代理,参考博客
1
2
3import os
os.environ['NO_PROXY'] = "mp.weixin.qq.com" -
设置标头
1
2
3
4headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"Cookie": "RK=N9tk1HjFWK; ...太长省略... skey=@ZhnRkc9u3"
} -
编写正则表达式,用于在url中提取推文的mid、idx和sn三个参数
请先在regex101上面验证正则表达式是否正确
1
2
3import re
reg_exp = re.compile(r'mid=(?P<mid>\w+?)\&.*?idx=(?P<idx>\d+)\&sn=(?P<sn>\w+?)\&', re.S) -
导入之前从网页上爬取的url,并从中提取出需要的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19## 打开csv文件
with open("hainanuniversity.csv", encoding="utf-8", mode="r") as f_r:
content = csv.reader(f_r) ## csv.reader返回一个可迭代的对象
for row in content: ## 迭代的元素为列表<class list>
if row == []: ## 列表非空判别
continue
## 获取每篇文章的信息
date = row[0] ## 日期<class 'str'>
title = row[1] ## 标题<class 'str'>
url = row[2] ## 链接<class 'str'>
## 正则提取url中的mid和sn
## findall返回一个列表,列表中包含一个元组[(mid,idx,sn)]
result = reg_exp.findall(url)
mid = result[0][0]
idx = result[0][1]
sn = result[0][2] -
设置post参数
1
2
3
4
5
6## 需要传入这三个参数,服务器才会返回点赞数、阅读量这些数据
data = {
"is_only_read": "1",
"is_temp_url": "0",
"appmsg_type": "9"
} -
设置url参数
1
2
3
4
5
6
7params = {
"__biz": "MzIwMzUxNjgzNw==", ## 这是公众号的唯一标识
"mid": mid, ## mid、sn、idx是文章的标识
"sn": sn,
"idx": idx,
"appmsg_token": "1176...太长省略...5tn" ## appmsg_token隔一段时间要更换
} -
使用
requests.post()
命令向服务器发出post请求,获取相关的参数1
2
3
4
5
6
7
8## post请求,并以json格式输出
## resp类型为字典<class 'dict'>,可以通过字段对其进行访问
resp = requests.post(request_url, headers=headers, data=data, params=params).json()
## 通过字段提取有效信息
read_num = resp["appmsgstat"]["read_num"] ## 阅读量
like_num = resp["appmsgstat"]["like_num"] ## 在看数
old_like_num = resp["appmsgstat"]["old_like_num"] ## 点赞数 -
将结果写入新的csv文件
1
2
3
4
5
6
7
8## 打开csv文件
f_w = open("HNU.csv", mode="w", encoding='utf-8-sig', newline='')
csvwriter = csv.writer(f_w)
## 一行的信息,分别对应日期、标题、阅读量、点赞数、在看数
item = [date, title, read_num, old_like_num, like_num, url]
## 按行写入csv文件
csvwriter.writerow(item)
完整代码
1 | import requests ## request库 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 文羊羽!