总结:带大家写一波微信公众号的爬取!谁说微信爬不了的
优采云 发布时间: 2020-10-22 08:01带大家去写一波微信公众号爬网!谁说微信无法攀登
x5
其他参数的含义可以根据经验和简单的测试来判断:
1.偏移
控制翻页的偏移参数
2.个计数
每页文章的数量
3.__ biz
官方帐户标识,不同的__biz对应于不同的官方帐户
4.pass_ticket
它应该是微信登录后返回的参数,
去年我尝试登录微信网络版本时,在返回的参数中看到了它,
但是现在微信网络版本已被正式禁止T_T。
5.appmsg_token
它还应该是登录微信后的标识参数,以及您阅读的微信官方帐户
相关,查看不同的微信公众号时的值也不同。
前三个变量参数很容易求解,但后两个参数似乎更难。但是,在测试之后,我们可以发现pass_ticket实际上是一个可选参数,因此我们可以忽略它。而且appmsg_token的有效期至少为10个小时,这段时间足以让我们抓取目标官方帐户的所有文章,因此只需直接将其复制,就无需浪费时间分析这些东西(您也应该知道您是否认为腾讯对白人卖淫(T_T)绝对不那么容易。编写一段代码对其进行简短测试:
import requests
session = requests.Session()
session.headers.update(headers)
session.cookies.update(cookies)
profile_url = '前面抓包得到的请求地址'
biz = 'MzAwNTA5NTYxOA=='
pass_ticket = ''
appmsg_token = '1055_YAmuAw2QG7dM3aTwSVZVqgtRdct6ilAMTwlz7g'
params = {
'action': 'getmsg',
'__biz': biz,
'f': 'json',
'offset': '0',
'count': '10',
'is_ok': '1',
'scene': '123',
'uin': '777',
'key': '777',
'pass_ticket': pass_ticket,
'wxtoken': '',
'appmsg_token': appmsg_token,
'x5': '0'
}
res = session.get(profile_url, params=params, verify=False)
print(res.text)
运行后,您会发现返回的数据如下:
似乎没有问题。重新调整打包代码以爬网正式帐户的所有文章链接。具体来说,核心代码实现如下:
'''获得所有文章的链接'''
def __getArticleLinks(self):
print('[INFO]: 正在获取目标公众号的所有文章链接...')
fp = open('links_tmp.json', 'w', encoding='utf-8')
article_infos = {}
params = {
'action': 'getmsg',
'__biz': self.cfg.biz,
'f': 'json',
'offset': '0',
'count': '10',
'is_ok': '1',
'scene': '123',
'uin': '777',
'key': '777',
'pass_ticket': self.cfg.pass_ticket,
'wxtoken': '',
'appmsg_token': self.cfg.appmsg_token,
'x5': '0'
}
while True:
res = self.session.get(self.profile_url, params=params, verify=False)
res_json = res.json()
can_msg_continue = res_json.get('can_msg_continue', '')
next_offset = res_json.get('next_offset', 10)
general_msg_list = json.loads(res_json.get('general_msg_list', '{}'))
params.update({'offset': next_offset})
for item in general_msg_list['list']:
app_msg_ext_info = item.get('app_msg_ext_info', {})
if not app_msg_ext_info: continue
title = app_msg_ext_info.get('title', '')
content_url = app_msg_ext_info.get('content_url', '')
if title and content_url:
article_infos[title] = content_url
if app_msg_ext_info.get('is_multi', '') == 1:
for article in app_msg_ext_info.get('multi_app_msg_item_list', []):
title = article.get('title', '')
content_url = article.get('content_url', '')
if title and content_url:
article_infos[title] = content_url
if can_msg_continue != 1: break
else: time.sleep(1+random.random())
json.dump(article_infos, fp)
fp.close()
print('[INFO]: 已成功获取目标公众号的所有文章链接, 数量为%s...' % len(list(article_infos.keys())))
运行后,我们可以获得目标官方帐户的所有文章链接:
现在,我们只需要基于这些文章链接来抓取文章的内容。在这里,我们使用python的第三方软件包pdfkit将每篇文章文章保存为pdf文件。具体来说,核心代码实现如下:
'''下载所有文章'''
def __downloadArticles(self):
print('[INFO]: 开始爬取目标公众号的所有文章内容...')
if not os.path.exists(self.savedir):
os.mkdir(self.savedir)
fp = open('links_tmp.json', 'r', encoding='utf-8')
article_infos = json.load(fp)
for key, value in article_infos.items():
print('[INFO]: 正在抓取文章 ——> %s' % key)
pdfkit.from_url(value, os.path.join(self.savedir, key+'.pdf'), configuration=pdfkit.configuration(wkhtmltopdf=self.cfg.wkhtmltopdf_path))
print('[INFO]: 已成功爬取目标公众号的所有文章内容...')
请注意,在使用pdfkit之前,您需要安装wkhtmltox。如下图所示:
运行的效果可能是这样的:
所有源代码
根据您自己的数据包捕获结果修改cfg.py文件:
## cfg.py
# 目标公众号标识
biz = 'MzAwNTA5NTYxOA=='
# 微信登录后的一些标识参数
pass_ticket = ''
appmsg_token = '1055_YAmuAw2QG7dM3aTwSVZVqgtRdct6ilAMTwlz7g~~'
# 安装的wkhtmltopdf.exe文件路径
wkhtmltopdf_path = r'D:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe'
12345678
## articlesSpider.py
import os
import time
import json
import pdfkit
import random
import requests
import warnings
warnings.filterwarnings('ignore')
'''微信公众号文章爬取类'''
class articlesSpider(object):
def __init__(self, cfg, **kwargs):
self.cfg = cfg
self.session = requests.Session()
self.__initialize()
'''外部调用'''
def run(self):
self.__getArticleLinks()
self.__downloadArticles()
'''获得所有文章的链接'''
def __getArticleLinks(self):
print('[INFO]: 正在获取目标公众号的所有文章链接...')
fp = open('links_tmp.json', 'w', encoding='utf-8')
article_infos = {}
params = {
'action': 'getmsg',
'__biz': self.cfg.biz,
'f': 'json',
'offset': '0',
'count': '10',
'is_ok': '1',
'scene': '123',
'uin': '777',
'key': '777',
'pass_ticket': self.cfg.pass_ticket,
'wxtoken': '',
'appmsg_token': self.cfg.appmsg_token,
'x5': '0'
}
while True:
res = self.session.get(self.profile_url, params=params, verify=False)
res_json = res.json()
can_msg_continue = res_json.get('can_msg_continue', '')
next_offset = res_json.get('next_offset', 10)
general_msg_list = json.loads(res_json.get('general_msg_list', '{}'))
params.update({'offset': next_offset})
for item in general_msg_list['list']:
app_msg_ext_info = item.get('app_msg_ext_info', {})
if not app_msg_ext_info: continue
title = app_msg_ext_info.get('title', '')
content_url = app_msg_ext_info.get('content_url', '')
if title and content_url:
article_infos[title] = content_url
if app_msg_ext_info.get('is_multi', '') == 1:
for article in app_msg_ext_info.get('multi_app_msg_item_list', []):
title = article.get('title', '')
content_url = article.get('content_url', '')
if title and content_url:
article_infos[title] = content_url
if can_msg_continue != 1: break
else: time.sleep(1+random.random())
json.dump(article_infos, fp)
fp.close()
print('[INFO]: 已成功获取目标公众号的所有文章链接, 数量为%s...' % len(list(article_infos.keys())))
'''下载所有文章'''
def __downloadArticles(self):
print('[INFO]: 开始爬取目标公众号的所有文章内容...')
if not os.path.exists(self.savedir):
os.mkdir(self.savedir)
fp = open('links_tmp.json', 'r', encoding='utf-8')
article_infos = json.load(fp)
for key, value in article_infos.items():
print('[INFO]: 正在抓取文章 ——> %s' % key)
key = key.replace('\\', '').replace('/', '').replace(':', '').replace(':', '') \
.replace('*', '').replace('?', '').replace('?', '').replace('“', '') \
.replace('"', '').replace('', '').replace('|', '_')
pdfkit.from_url(value, os.path.join(self.savedir, key+'.pdf'), configuration=pdfkit.configuration(wkhtmltopdf=self.cfg.wkhtmltopdf_path))
print('[INFO]: 已成功爬取目标公众号的所有文章内容...')
'''类初始化'''
def __initialize(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 QBCore/4.0.1295.400 QQBrowser/9.0.2524.400 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2875.116 Safari/537.36 NetType/WIFI MicroMessenger/7.0.5 WindowsWechat'
}
self.cookies = {
'wxuin': '913366226',
'devicetype': 'iPhoneiOS13.3.1',
'version': '17000c27',
'lang': 'zh_CN',
'pass_ticket': self.cfg.pass_ticket,
'wap_sid2': 'CNK5w7MDElxvQU1fdWNuU05qNV9lb2t3cEkzNk12ZHBsNmdXX3FETlplNUVTNzVfRmwyUUtKZzN4QkxJRUZIYkMtMkZ1SDU5S0FWQmtSNk9mTTQ1Q1NDOXpUYnJQaDhFQUFBfjDX5LD0BTgNQJVO'
}
self.profile_url = 'https://mp.weixin.qq.com/mp/profile_ext'
self.savedir = 'articles'
self.session.headers.update(self.headers)
self.session.cookies.update(self.cookies)
'''run'''
if __name__ == '__main__':
import cfg
spider = articlesSpider(cfg)
spider.run()
要简单。如果不能的话,请将我添加到企鹅群组中,以接收视频教程和源代码。私人消息编辑器01