爬取微信公众号发布的所有文章(包括阅读数,在看数,点赞数)
这次写爬虫。我爬取了某个微信公众号的全部文章的
-
文章链接 url
-
文章标题 title
-
发布时间 update_time
-
封面链接 cover
-
阅读数 read_num
-
在看数 like_num
若想直接拿代码来用,可以直接跳到最后。
首先要找到所有文章链接地址
一般来说,网上是搜不到某个公众号的全部文章的。但是我们利用 微信公众号平台 就能够一次性找到。
要用到它,肯定需要先注册登录一个微信公众号。当我们来到后台界面。
进入素材管理——> 新建图文——> (上方的)超链接界面
当我们打开开发者工具,搜索点击某个公众号后,就会抓到一个get请求包
它返回的就是文章相关的信息(包含了,文章链接,文章标题,创建时间,封面地址等)
因此找到请求后,我们开始构造
url 肯定是不变的 https://mp.weixin.qq.com/cgi-bin/appmsg
请求头复制粘贴过去
get请求的参数params也能直接进行复制
这里的begin代表的是页数,如果需要更多数据,肯定是需要翻页的。多次请求改变begin的值就可以了
第一部分的代码如下
import requests
import time
import datetime
import pytz
url="https://mp.weixin.qq.com/cgi-bin/appmsg"
#我这里先把数据写入到txt文件中
f=open("微信公众号文章.txt",mode="w",encoding="utf-8")
headers={
#这里是你自己的headers
}
params={
#这里是你自己的params
}
begin=0
#发起第一次请求
resp=requests.get(url,headers=headers,params=params,verify=False)
data = resp.json()
while True:
time.sleep(5)
#data['app_msg_list']里面装载的就是我们需要的数据
if len(data['app_msg_list'])==0:
#可能数据请求完了,可能请求失败,可能你的微信公众号请求被禁用一段时间(因为爬数据过于频繁,被发现了)
break
for app_msg in data['app_msg_list']:
title = app_msg['title'] #文章标题
link = app_msg['link'] #文章链接
update_time=app_msg['update_time'] #文章创建时间,为时间戳
#将时间戳转为 年月日,时分秒
update_time = datetime.datetime.fromtimestamp(int(update_time), pytz.timezone('Asia/Shanghai')).strftime('%m/%d/%Y %H:%M:%S')
cover =app_msg['cover'] #文章封面图片地址
#请求下一页的数据
begin+=1
params['begin']=begin*5
resp = requests.get(url, headers=headers, params=params,verify=False)
data = resp.json()
print(resp)
要值得注意的是,在第一步时候,如果请求过于频繁,Cookie会被服务器暂时封禁(自测是几十分钟)。每次请求之前间隔几秒休息,也不太好使。这时候就只能换一个公众号或者等个几十分钟。再次运行。(一次能抓60页左右的数据)
然后我们如何获取到文章的详细信息呢?包括阅读数,在看数
我们知道,从PC端微信里面,进入公众号后点击文章。下面会有阅读数,在看数等数据信息。直接从浏览器看文章的话是没有的。
因为PC端微信请求文章内容,附带了一些参数,是浏览器没有的。导致服务器那边没有返回这些实时数据(阅读数,在看数)
所有我们要用工具抓包。抓取微信在点开文章时发送的请求。
我这里使用的抓包工具是 Fiddler。官网下载地址为:
链接: Fidder抓包工具官网地址.
简单的使用我就不交了,能抓包就行。
监听的时候,我们随便点击我们要爬取的公众号的随便一篇文章
抓到了一个以** /mp/getappmsgext? ** 为POST提交的 url 地址。如下图
通过分析返回的response里面的json数据。就有我们的阅读数(read_num)和在看数(like_num)。如下图
当然要提取页面其它数据,都是可以的。
因此,我们根据该POST的请求信息,构造requests,就能拿到某一篇文章阅读数和在看数了。详细见如下代码
(提示!如果你想直接拿代码用,你自己需要弄到参数有5个)。
- phoneCookie
- uin
- pass_ticket
- appmsg_token
- key
# 获取阅读数和点赞数
import requests
import time
def getMoreInfo(link):
# 获得mid,_biz,idx,sn 这几个在link中的信息。
mid = link.split("&")[1].split("=")[1]
idx = link.split("&")[2].split("=")[1]
sn = link.split("&")[3].split("=")[1]
_biz = link.split("&")[0].split("_biz=")[1]
#该4个参数,需要自己从抓的包里面的请求头里面去获取,
uin = 'MTcwMDU3OTA4Mg=='
pass_ticket = 'FHAPWEyH4En5JI9SyHXcUtAfV1pxn/W/BMXpVnaOGQDhbD709+wejbXJCVLDGjvz'
appmsg_token = '1130_Tml%2BYcZMk8oJAMuu6NYwpkTS-XtM-kz5LNJQv6N9AvC_sFfoc6dwKaHOYy4vNTEnvq7_bc6-HDgxo9mk'
key = "7f92ccecf3278296917b0c74884016e74c45da721ac3a5c1f6895b2ea9a7a8f9f555af415fe9e63d2ed2ae943c7a643907e586cc622938b8d942055605523620b14d99c0368ea9a9202af4adf3311a1ebba37f6cb75b1041e84f02b59ae30e9ed498d996f66f75b9b7aa12403d117dd01f2f92c19b04e5aba3bcb669659551d0"
# 目标url
url = "http://mp.weixin.qq.com/mp/getappmsgext"
# 添加Cookie避免登陆操作。Cookie需要自己从抓的包里面去获取
phoneCookie = "rewardsn=; wxtokenkey=777; wxuin=1700579082; lang=zh_CN; appmsg_token=1130_Tml%2BYcZMk8oJAMuu6NYwpkTS-XtM-kz5LNJQv6N9AvC_sFfoc6dwKaHOYy4vNTEnvq7_bc6-HDgxo9mk; devicetype=Windows10x64; version=63030532; pass_ticket=FHAPWEyH4En5JI9SyHXcUtAfV1pxn/W/BMXpVnaOGQDhbD709+wejbXJCVLDGjvz; wap_sid2=CIqO86oGEooBeV9IUGFHMElKRUJpdENjbGd0QWxxd0RDUHEwWm5IV1JTMlFDVExncGVuYnh1bmRwSUpxVHV6U1hCbG5JQXE1UTh5V3FlOUh1V0JPeUxwcFVrR3V0REZ0NGJGRHB2VVpqcS1Md3J6WHlsY3VPQzkzOHVWTlk4NDlmTFFjOFgzdDgwVGJrY1NBQUF+MOO54YkGOA1AAQ=="
#这里的"User-Agent"最好为手机浏览器的标识
headers = {
"Cookie": phoneCookie,
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400"
}
# 添加data,`req_id`、`pass_ticket`。
data = {
"is_only_read": "1",
"is_temp_url": "0",
"appmsg_type": "9",
'reward_uin_count': '0'
}
#根据获取到的参数,构造PSOT请求的params
params = {
"__biz": _biz,
"mid": mid,
"sn": sn,
"idx": idx,
"key": key,
"pass_ticket": pass_ticket,
"appmsg_token": appmsg_token,
"uin": uin,
"wxtoken": "777",
}
#post请求提交后,将返回的respone转为json
json = requests.post(url, headers=headers, data=data, params=params).json()
#获取到阅读数
read_num=json['appmsgstat']['read_num']
# 获取到在看书
like_num=json["appmsgstat"]["like_num"]
print(read_num,like_num)
#随便某一篇文章的url地址
url="http://mp.weixin.qq.com/s?__biz=MjM5Nzc5OTcxNA==&mid=2651014142&idx=1&sn=5f00452e553dad1f0621ca82b1a674bd&chksm=bd2391b38a5418a5dbcdeacbd738289fc8c421c7f0b125b97be21f65463b87d12d1c9ce75436#rd"
getMoreInfo(url)
同样值得注意的是,在第二步的时候,我们也同样不能请求过于频繁,间隔几秒请求 没有问题。如果被禁用了,再次抓包即可。
这些一下来就能根据公众号的名称,获取到它下面的所有文章的详细信息。
如果写得不好的地方请指正,欢迎和我学习交流!
更多推荐
所有评论(0)