好友
阅读权限 10
听众
最后登录 1970-1-1
本帖最后由 subney 于 2021-6-28 09:27 编辑
大家不知道有没有遇到过这样的痛点——
找到一个宝藏级的公众号,看完最近几天的推文不过瘾,就翻到“历史消息”,继续浏览。
这个时候,就会回到一个很懊恼的问题:越往后看,下滑操作越多,然后看完一篇文章回来,“历史消息”页面并没有保存离开的位置,于是乎,继续吭哧吭哧地往下滑……
这么来上几回,**手指都给磨秃了有木有!!!**
与其等待微信改进这个小问题,不如自己想办法解决,最近学python爬虫,当然用python解决啦。
# 工作准备:
1. 安装Python环境,安装requests库
2. 安装抓包神器:Fiddler(需要安装SSL证书)
3. 安装VSCode编辑器(Pycharm也可以的)
4. 安装最新版PC版微信
# 工作步骤:
1. 在公众号点击历史消息按钮时,用fiddler抓包
2. 获取请求Header
原始的header是一行行的字符串,需要重新格式化成字典
```
raw='''
Host: mp.weixin.qq.com
Connection: keep-alive
...
'''
def formate_headers(raw:str)->dict:
headers={}
lines=raw.splitlines()
for line in lines:
if not line:
continue
# print(line)
key,value=line.split(':',maxsplit=1)
key=key.strip()
value=value.strip()
headers[key]=value
return headers
```
3. 分析请求url
```
API_PATTERN='https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=MjM5MjQyOTEyMA==&f=json&offset=10&count=10&
```
最重要的是两个请求参数offset和count
offset决定返回的文章序号(倒序),主要修改这个就可以不断获取新的文章信息。
count决定返回的文章信息数量
4. 用requests发起请求
```
import requests
import time
def get_json(index):
index=0
session=requests.Session()
session.headers=HEADERS
session.verify=False
while True:
list_api=API_PATTERN.format(offset=index)
data_dict=session.get(list_api).json()
#获取列表为空,结束爬虫
if data_dict['errmsg'].lower() != 'ok':
break
time.sleep(5)
```
注意!爬取json时,需要设置延时!别企鹅给拉黑了。
5. 分析json
```
{
"ret": 0,
"errmsg": "ok",
"msg_count": 10,
"can_msg_continue": 1,
"general_msg_list": "{\"list\":[{\"comm_msg_info\":{\"id\":1000001538,\"type\":49,\"datetime\":1624710480,\"fakeid\":\"2392429120\",\"status\":2,\"content\":\"\"},
}
```
我们需要的信息在**general_msg_list**,因为value是一个字符串,需要再次json解析
```
if isinstance(msg_list,str):
msg_list=json.loads(msg_list)['list']
```
然后迭代列表,提取需要的信息。我想到的提取方法有两种
- 分析数据层级,精准提取
- 暴力迭代
根据自身需要,我用了第二种
```
class Detail_Url_Extractor:
def __init__(self,key:str,pattern:str) -> None:
self.__key=key
self.__pattern=pattern
self.__res=None
#递归调用,分析每一个嵌套字典的k-v
#key:目标字段
#pattern:字段的值
#这里是找到含有关键字的title字段,然后提取文章地址
def __extract(self,obj):
if self.__res:
return
if isinstance(obj,list):
for item in obj:
self.__extract(item)
if isinstance(obj,dict):
if self.__key in obj and self.__pattern in obj[self.__key]:
self.__res = (obj['title'],obj['content_url'])
return
for k,v in obj.items():
if isinstance(v,list):
self.__extract(v)
elif isinstance(v,dict):
self.__extract(v)
def extract(self,obj):
self.__res=None
self.__extract(obj)
return self.__res
```
代码不知为啥又是排版错误。
这里的实现有点丑。本来只要一个递归函数就行,但是我不知道怎么从递归返回结果,所以需要一个作用域保存结果,因此有了一个类
6. 获取文章地址后的操作,我也想到两个办法
a.将文章地址的标题做成网页超链接,超链接集合起来做成一个网页,就可以在浏览器中访问,而且可以保留浏览记录。问题是,地址可能会过期
b.将地址全部爬下来就好了,简单粗暴!
7. 分享昨天爬到的信息,是几百张沙雕动图地址,有兴趣的小伙伴可以自己爬下来看看。
[图片地址文本文件](https://wwe.lanzoui.com/i8pc0qrjlbe)[/md]
免费评分
查看全部评分
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。