利用Python爬虫采集微信公众号文章

el/2023/12/3 1:56:56

开发工具

python版本 : 3.6.4
相关模块:
pdfkit模块;
requests模块;
以及一些Python自带的模块。
抓包工具: fiddler

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤
QQ群:623406465


环境搭建

  1. python 环境
    安装Python并添加到环境变量,pip安装需要的相关模块即可。
  2. fiddler 环境
    去官网下载最新版本的安装包直接安装。
    fiddler官网

原理简介

首先,我们打开fiddler这个抓包软件,其界面如下:
在这里插入图片描述
然后,我们设置一下过滤规则以过滤掉没用的数据包,因为我们只想抓取微信相关的数据包而已,而不想其他没用的数据包干扰我们的分析,就像这样:
在这里插入图片描述
接着我们在电脑端登录微信,并随便找个公众号,查看它的历史文章列表。就像这样:
在这里插入图片描述
不断滚动鼠标滚轮,以查看该公众号更多的历史文章数据。此时,我们可以在fiddler里看到出现了类似如下图所示的情况:
在这里插入图片描述

显然,红框里的https请求应该就是获得该微信公众号发的文章相关的数据的请求了。现在,我们来分析一下这个请求。显然,该请求的链接地址构成为:
在这里插入图片描述
接着看看请求头,请求头的话在这能看到:
在这里插入图片描述
感觉有个user-agent就足够了:

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'}

接着看看cookies,在这(应该直接复制到代码里就行了):
在这里插入图片描述

最后,再看看发送这个请求需要携带哪些参数吧,在这:
在这里插入图片描述
即:

action
__biz
f
offset
count
is_ok
scene
uin
key
pass_ticket
wxtoken
appmsg_token
x5

经过测试,我们可以发现如下参数是可以固定的:

action
f
is_ok
scene
uin
key
wxtoken
x5

其他参数的含义我们则可以根据经验和简单的测试进行判断:

1.offset
控制翻页的偏移量参数
2.count
每页的文章数量
3.__biz
公众号标识, 不同的__biz对应不同的公众号
4.pass_ticket
应该是微信登录之后返回的参数吧,
去年尝试模拟登录微信网页版的时候看到返回的参数里就好像有它,
但是现在微信网页版已经被官方封了T_T。
5.appmsg_token
应该也是微信登录之后的一个标识参数吧, 而且和阅读的微信公众号
有关,查看不同的微信公众号时该值也是不同的。

前面三个可变参数都好解决,后面两个参数似乎就比较难办了。不过经过测试,我们可以发现pass_ticket其实是一个可有可无的参数,所以我们可以不管它。而appmsg_token的有效期至少有10几个小时,这段时间足够我们爬取目标公众号的所有文章了,所以直接复制过来就可以了,没必要浪费时间分析这玩意(随便想想也应该知道白嫖腾讯肯定没那么容易的T_T)。写个代码简单测试一下:

import requestssession = 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: continuetitle = app_msg_ext_info.get('title', '')content_url = app_msg_ext_info.get('content_url', '')if title and content_url:article_infos[title] = content_urlif 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_urlif can_msg_continue != 1: breakelse: 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'
## 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 = cfgself.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: continuetitle = app_msg_ext_info.get('title', '')content_url = app_msg_ext_info.get('content_url', '')if title and content_url:article_infos[title] = content_urlif 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_urlif can_msg_continue != 1: breakelse: 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('>', '').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 cfgspider = articlesSpider(cfg)spider.run()

http://www.ngui.cc/el/1524939.html

相关文章

一篇文章带你学会使用Python爬虫利器Fiddler

Fiddler不但能截获各种浏览器发出的HTTP请求, 也可以截获各种智能手机发出的HTTP/HTTPS请求。 Fiddler能捕获IOS设备发出的请求&#xff0c;比如IPhone, IPad, MacBook. 等等苹果的设备。 同理&#xff0c;也可以截获Andriod&#xff0c;Windows Phone的等设备发出的HTTP/HTT…

用python给你带来你的桃花运,详细解析画一棵表白树!

程序员就只能简简单单的用手里的代码来实现自己最直接的想法。-------------鲁迅表示这句话他没说过—————————————————————————————————————————————在家上网课贼无聊&#xff0c;于是复习以前的知识点&#xff0c;瞥到之前用递归…

用python爬猫眼电影,简单网站却有 “多重思路” !

七夕不看电影就爬电影吧。猫眼电影作为爬虫的必备练手网站&#xff0c;相信每个人都试过吧&#xff1f; 那么这篇文章&#xff0c;我就再爬一次猫眼电影&#xff0c;而且用上正则和xpath一起&#xff0c;分别保存为excel表格和csv表格&#xff0c;&#xff08;text文本这个就太…

本周 GitHub 速览:自动化当道,破密、Python爬虫各凭本事

摘要&#xff1a;安全门外汉&#xff0c;如何在不知道密钥或密码的情况下&#xff0c;破解哈希得到原文&#xff0c;Ciphey 会告诉你当中的密码。说到 auto 智能爬虫会基于上一次的爬虫经历进一步学习以获得类似信息。最优雅的莫属于 Diagram as Code——Diagrams&#xff0c;用…

Python采集网易云音乐

大家好&#xff0c;我是不温卜火&#xff0c;是一名计算机学院大数据专业大三的学生&#xff0c;昵称来源于成语—不温不火&#xff0c;本意是希望自己性情温和。作为一名互联网行业的小白&#xff0c;博主写博客一方面是为了记录自己的学习过程&#xff0c;另一方面是总结自己…

Python自动化办公:PDF批量处理(打水印、加密码、分类放置)

在日常工作中&#xff0c;要保护一下我们的商业机密嘛~ 如果按名单向客户逐一发文件&#xff0c;如果就发几份&#xff0c;那么可以采取用pdf软件逐份编辑&#xff0c;打个水印、加个密码咯。但面对成百上千份文件&#xff0c;就需要批量处理了&#xff01;菜鸡在熬夜加班后终于…

Python爬虫教程,采集bilibili弹幕并生成词云

Python爬取bilibili弹幕并生成词云 目标网站&#xff1a; 我这里以 TES vs SN 第四场决胜局为例&#xff1a; 探索经历&#xff1a; 很多人学习python&#xff0c;不知道从何学起。 很多人学习python&#xff0c;掌握了基本语法过后&#xff0c;不知道在哪里寻找案例上手。 …

Python+selenium通过定时任务,在指定时间自动运行程序

创建定时任务&#xff0c;在指定的时间自动运行测试用例 设置指定的时间让自动化python脚本自动运行起来&#xff0c;不需要人为手动点击启动运行 很多人学习python&#xff0c;不知道从何学起。 很多人学习python&#xff0c;掌握了基本语法过后&#xff0c;不知道在哪里寻找…

舅舅喜欢打牌,我用python给他写了个抽奖小程序!希望能够帮到他

前言&#xff1a; 舅舅是个赌瘾很重的人&#xff0c;特别对麻将更是独爱&#xff0c;为此全家人很烦恼&#xff0c;对此就想着用“以毒攻毒”专门写个抽奖小程序给舅舅&#xff0c;希望能帮他缓解&#xff0c;分散&#xff0c;转移牌瘾&#xff0c;回到美好生活中&#xff01;…

JS逆向教程:Python采集今日头条视频

最近在做今日头条文章数据抓取的过程中&#xff0c;发现视频地址的获取较为复杂。在源码与浏览器配合下发现对应的解决思路&#xff0c;故此记录一下。 很多人学习python&#xff0c;不知道从何学起。 很多人学习python&#xff0c;掌握了基本语法过后&#xff0c;不知道在哪里…