querylist采集微信公众号文章(批量获取公众号推送超链接的原理(图)介绍)

优采云 发布时间: 2022-01-17 22:08

  querylist采集微信公众号文章(批量获取公众号推送超链接的原理(图)介绍)

  一、前言

  二、准备

  三、正式开始

  四、结束语

  一、前言

  前几天书文问我能不能爬取微信公众号“北京邮教部”的历史动态,分析最多的成绩和科目。之前没做过微信公众号爬虫,所以研究了一下,发现了这个文章。

  二、准备三、正式开始(一)批量获取之前公众号推送的url链接1.微信后台插入其他公众号推送超链接的原理公众号

  如果要批量抓取微信公众号过去的推送,最大的问题是如何获取这些推送的url链接。因为通常我们点击一​​个推送时,微信会随机生成一个url链接,而这个随机生成的url与公众号推送的其他url没有任何关联。因此,如果我们要批量抓取公众号的所有推送,需要手动点击每条推送,复制每条推送的url链接。这显然是不现实的。在广泛查阅各种资料后,我学会了如何爬取公众号所有文章this文章的方法。

  这种方式的原理是,当我们登录微信公众号后台编辑图文素材时,可以在素材中插入其他公众号的推送链接。这里,微信公众号后台会自动调用相关API,返回公众号推送的所有长链接列表。

  

  我们打开Chrome浏览器的查看模式,选择网络,然后在编辑超链接界面的公众号搜索栏中输入“北京邮政家教部”,搜索并选择公众号,发现一个刷新的网络以“开头” appmsg”开头的内容,这是我们分析的目标。

  

  我们点击“appmsg”开头的内容,解析请求的url:

  https://mp.weixin.qq.com/cgi-bin/appmsg?action=list_ex&begin=0&count=5&fakeid=MjM5NDY3ODI4OA==&type=9&query=&token=1983840068&lang=zh_CN&f=json&ajax=1

  链接分为三个部分:

  request的基本部分?action=list_ex常用于动态网站,实现不同的参数值生成不同的页面或返回不同的结果&begin=0&count=5&fakeid=MjM5NDY3ODI4OA==&type=9&query=&token= 1983840068&lang=zh_CN&f =json&ajax=1 设置各种参数2.获取Cookie和User-Agent

  如果使用Python的Requests库直接访问url,是无法正常获取结果的。原因是在使用网页版微信公众号在后台插入超链接时,我们处于登录状态,但是当我们使用python直接访问时,我们并没有处于登录状态。因此,我们需要在访问时手动获取Cookie和User-Agent,并在使用Python的Requests库访问时将它们传递到headers参数中。这里说一下,我把公众号标识符 fakeid 和 token 参数保存在一个 yaml 文件中,方便爬取时加载。

  cookie : appmsglist_action_3899……

user_agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64)……

fakeid : MzI4M……

token : "19……

  在python代码中加载如下:

  import yaml

with open("wechat.yaml", "r") as file:

file_data = file.read()

config = yaml.safe_load(file_data)

headers = {

"Cookie": config['cookie'],

"User-Agent": config['user_agent']

}

  3.设置url参数

  然后我们设置要请求的url链接的参数:

  # 请求参数

url = "https://mp.weixin.qq.com/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"

}

  这里,count 是请求返回的信息数,begin 是当前请求的页数。当begin设置为0时,会以json格式返回最近五次推送信息,以此类推。

  4.开始爬取

  通过一个循环,begin的值每次加1,循环爬取:

  i = 0

while True:

begin = i * 5

params["begin"] = str(begin)

# 随机暂停几秒,避免过快的请求导致过快的被查到

time.sleep(random.randint(1,10))

resp = requests.get(url, headers=headers, params = params, verify=False)

# 微信流量控制, 退出

if resp.json()['base_resp']['ret'] == 200013:

print("frequencey control, stop at {}".format(str(begin)))

time.sleep(3600)

continue

# 如果返回的内容中为空则结束

if len(resp.json()['app_msg_list']) == 0:

print("all ariticle parsed")

break

msg = resp.json()

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']))

with open("app_msg_list.csv", "a",encoding='utf-8') as f:

f.write(info+'\n')

print(f"第{i}页爬取成功\n")

print("\n".join(info.split(",")))

print("\n\n---------------------------------------------------------------------------------\n")

# 翻页

i += 1

  爬了大概50页的时候,遇到如下错误:{'base_resp': {'err_msg': 'freq control', 'ret': 200013}}这是因为微信公众号有流量限制,等一个小时就好了. 我在这里使用以下代码来解决它:

  # 微信流量控制

if resp.json()['base_resp']['ret'] == 200013:

print("frequencey control, stop at {}".format(str(begin)))

time.sleep(3600)

continue

  对于每条爬取的信息,对其进行解析并将其存储在一个 csv 文件中:

  msg = resp.json()

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']))

with open("python小屋.csv", "a",encoding='utf-8') as f:

f.write(info+'\n')

  5.完整代码

  完整代码如下:

  #!/usr/bin/env python

# -*- encoding: utf-8 -*-

'''

@File : Spider.py

@Time : 2021/06/04 02:20:24

@Author : YuFanWenShu

@Contact : 1365240381@qq.com

'''

# here put the import lib

import json

import requests

import time

import random

import yaml

with open("wechat.yaml", "r") as file:

file_data = file.read()

config = yaml.safe_load(file_data)

headers = {

"Cookie": config['cookie'],

"User-Agent": config['user_agent']

}

# 请求参数

url = "https://mp.weixin.qq.com/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语句

# 也方便重新运行时设置页数

with open("app_msg_list.csv", "w",encoding='utf-8') as file:

file.write("文章标识符aid,标题title,链接url,时间time\n")

i = 0

while True:

begin = i * 5

params["begin"] = str(begin)

# 随机暂停几秒,避免过快的请求导致过快的被查到

time.sleep(random.randint(1,10))

resp = requests.get(url, headers=headers, params = params, verify=False)

# 微信流量控制, 退出

if resp.json()['base_resp']['ret'] == 200013:

print("frequencey control, stop at {}".format(str(begin)))

time.sleep(3600)

continue

# 如果返回的内容中为空则结束

if len(resp.json()['app_msg_list']) == 0:

print("all ariticle parsed")

break

msg = resp.json()

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']))

with open("app_msg_list.csv", "a",encoding='utf-8') as f:

f.write(info+'\n')

print(f"第{i}页爬取成功\n")

print("\n".join(info.split(",")))

print("\n\n---------------------------------------------------------------------------------\n")

# 翻页

i += 1

  6.爬取结果

  最终结果保存在 csv 文件中,一共 565 条推送消息:

  

  (二)对每次推送进行爬取,提取需要的信息1.对每次推送进行遍历和爬取

  从 csv 文件中读取每次推送的 url 链接,并使用 Requests 库抓取每次推送的内容:

  with open("app_msg_list.csv","r",encoding="utf-8") as f:

data = f.readlines()

n = len(data)

for i in range(n):

mes = data[i].strip("\n").split(",")

if len(mes)!=4:

continue

title,url = mes[1:3]

if i>0:

r = requests.get(eval(url),headers=headers)

if r.status_code == 200:

text = r.text

projects = re_project.finditer(text)

  2.提取信息并写入文件

  我们需要提取的是每个导师信息的年级和科目。通过观察推送结构,我决定使用正则表达式进行提取。

  

  有的家教订单长时间没有回复,会在多个帖子中重复出现,从而影响我们的统计结果。我决定用数字来识别不同的辅导信息,相同的数字只会计算一次。所以使用下面的正则表达式来匹配:

<p>re_project = re.compile(r">编号(.*?)年级(.*?)科目(.*?)科目(.*?)年级(.*?)编号(.*?)年级(.*?)科目(.*?)

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线