python爬⾍爬取超链接的⽂字_Python爬⾍实战练习:爬取微
信公众号⽂章
前⾔
本⽂的⽂字及图⽚来源于⽹络,仅供学习、交流使⽤,不具有任何商业⽤途,版权归原作者所有,如有问题请及时联系我们以作处理。
作者:徐洲更
为了实现该爬⾍我们需要⽤到如下⼯具
Chrome浏览器
Python 3 语法知识
Python的Requests库
此外,这个爬取程序利⽤的是微信公众号后台编辑素材界⾯。原理是,当我们在插⼊超链接时,微信会调⽤专门的API(见下图),以获取指定公众号的⽂章列表。因此,我们还需要有⼀个公众号。
正式开始
我们需要登录微信公众号,点击素材管理,点击新建图⽂消息,然后点击上⽅的超链接。
接着,按F12,打开Chrome的开发者⼯具,选择Network
此时在之前的超链接界⾯中,点击「选择其他公众号」,输⼊你需要爬取的公众号(例如中国移动)
此时之前的Network就会刷新出⼀些链接,其中以"appmsg"开头的便是我们需要分析的内容
我们解析请求的URL
mp./cgi-bin/appmsg?action=list_ex&begin=0&count=5&fakeid=MzI1MjU5MjMzNA==&type=9&query=&token=143406284&lang=zh_CN 它分为三个部分
mp./cgi-bin/appmsg: 请求的基础部分
action=list_ex: 常⽤于动态⽹站,实现不同的参数值⽽⽣成不同的页⾯或者返回不同的结果
&begin=0&count=5&fakeid: ⽤于设置?⾥的参数,即begin=0, count=5
通过不断的浏览下⼀页,我们发现每次只有begin会发⽣变动,每次增加5,也就是count的值。
接着,我们通过Python来获取同样的资源,但直接运⾏如下代码是⽆法获取资源的
import requests
url = "mp./cgi-bin/appmsg?action=list_ex&begin=0&count=5&fakeid=MzI1MjU5MjMzNA==&type=9&query=&token=1957521839&lang=zh_(url).json()
# {'ba_resp': {'ret': 200003, 'err_msg': 'invalid ssion'}}
我们之所以能在浏览器上获取资源,是因为我们登录了微信公众号后端。⽽Python并没有我们的登录信息,所以请求是⽆效的。我们需要
在requests中设置headers参数,在其中传⼊Cookie和Ur-Agent,来模拟登陆
治疗湿疹的偏方由于每次头信息内容都会变动,因此我将这些内容放⼊在单独的⽂件中,即"wechat.yaml",信息如下
cookie: ua_
ur_agent: Mozilla/
之后只需要读取即可
# 读取cookie和ur_agent
贾宝玉人物介绍
import yaml
with open("wechat.yaml", "r") as file:
file_data = ad()
config = yaml.safe_load(file_data)
headers = {
"Cookie": config['cookie'],
"Ur-Agent": config['ur_agent']
鬼字成语}
<(url, headers=headers, verify=Fal).json()
在返回的JSON中,我们就看到了每个⽂章的标题(title), 摘要(digest), 链接(link), 推送时间(update_time)和封⾯地址(cover)等信息。
appmsgid是每⼀次推送的唯⼀标识符,aid则是每篇推⽂的唯⼀标识符。
实际上,除了Cookie外,URL中的token参数也会⽤来限制爬⾍,因此上述代码很有可能输出会是{'ba_resp': {'ret': 200040, 'err_msg': 'invalid csrf token'}}
接着我们写⼀个循环,获取所有⽂章的JSON,并进⾏保存。
import json
import requests
import time
import random
import yaml
with open("wechat.yaml", "r") as file:
file_data = ad()
config = yaml.safe_load(file_data)
headers = {
"Cookie": config['cookie'],
"Ur-Agent": config['ur_agent']
}
# 请求参数
url = "mp./cgi-bin/appmsg"
begin = "0"
params = {
"action": "list_ex",
"begin": begin,
"count": "5",
海边踏浪"fakeid": config['fakeid'],
"type": "9",
"token": config['token'],
"lang": "zh_CN",
"f": "json",
"ajax": "1"
荧蒽}
# 存放结果
app_msg_list = []
# 在不知道公众号有多少⽂章的情况下,使⽤while语句
# 也⽅便重新运⾏时设置页数
i = 0
while True:
begin = i * 5
params["begin"] = str(begin)
# 随机暂停⼏秒,避免过快的请求导致过快的被查到
time.sleep(random.randint(1,10))
resp = (url, headers=headers, params = params, verify=Fal)
# 微信流量控制, 退出
if resp.json()['ba_resp']['ret'] == 200013:
print("frequencey control, stop at {}".format(str(begin)))
break
# 如果返回的内容中为空则结束
if len(resp.json()['app_msg_list']) == 0:
print("all ariticle pard")
break
app_msg_list.append(resp.json())
# 翻页
i += 1
外齿轮在上⾯代码中,我将fakeid和token也存放在了"wechat.yaml"⽂件中,这是因为fakeid是每个公众号都特有的标识符,⽽token则会经常性变动,该信息既可以通过解析URL获取,也可以从开发者⼯具中查看
在爬取⼀段时间后,就会遇到如下的问题
浙组词{'ba_resp': {'err_msg': 'freq control', 'ret': 200013}}
此时你在公众号后台尝试插⼊超链接时就能遇到如下这个提⽰
这是公众号的流量限制,通常需要等上30-60分钟才能继续。为了完美处理这个问题,你可能需要申请多个公众号,可能需要和微信公众号的登录系统⽃智⽃勇,或许还需要设置代理池。
但是我并不需要⼀个⼯业级别的爬⾍,只想爬取⾃⼰公众号的信息,因此等个⼀⼩时,重新登录公众号,获取cookie和token,然后运⾏即可。我可不想⽤⾃⼰的兴趣挑战别⼈的饭碗。
最后将结果以JSON格式保存。
# 保存结果为JSON
json_name = "mp_data_{}.json".format(str(begin))
with open(json_name, "w") as file:
file.write(json.dumps(app_msg_list, indent=2, ensure_ascii=Fal))
或者提取⽂章标识符,标题,URL,发布时间这四列信息,保存成CSV。
info_list = []
for msg in app_msg_list:
if "app_msg_list" in msg:
for item in msg["app_msg_list"]:
info = '"{}","{}","{}","{}"'.format(str(item["aid"]), item['title'], item['link'], str(item['create_time']))经济困难
info_list.append(info)
# save as csv
with open("app_msg_list.csv", "w") as file:
file.writelines("n".join(info_list))
下⼀篇,将介绍如何根据每个⽂章的连接地址,来获取每篇⽂章的阅读量信息。
参考资料
blog.csdn/kindred_joe/article/details/99289890
blog.csdn/qq_28804275/article/details/82150874
最终代码如下(代码可能有bug,谨慎使⽤),使⽤⽅法为python wechat_parr.py wechat.yaml
import json
import requests
import time