【Python爬虫】微信公众号历史文章和文章评论API分析

上一篇文章爬取微信公众号文章信息准备工作介绍了微信公众号历史文章和文章评论API的组成情况,历史文章API格式:https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=MjM5NjAxOTU4MA==&f=json&offset=10&count=10&is_ok=1&scene=126&uin=777&key=777&pass_ticket=tsN5weBAV13S7TjerqBeu0m84CMPMmPz4P7lb8bvDk90y1LP%2F1j46CUzFqDsMuRj&wxtoken=&appmsg_token=986_Zxzm8ptDJ39%252BC1UbkzPrFKd_laYeOCk5cVFX9A~~&x5=1&f=json
文章评论API格式:https://mp.weixin.qq.com/mp/appmsg_comment?action=getcomment&scene=0&__biz=MjM5NjAxOTU4MA==&appmsgid=3009217642&idx=2&comment_id=578089232589930496&offset=0&limit=100&uin=777&key=777&pass_ticket=v+7PaoESYfMrxgXJpqOkfXV4Y2+gYNPPJfSSmzPXfeiuNrNiBeEcs+8b//Yit5sd&wxtoken=777&devicetype=android-26&clientversion=2607033b&appmsg_token=986_jbuKqpV9lCZ1cb787Tem5V5n6JKpU9TrOFUZRE5esVxnBK7IR-TsZiXLRNaO1tnfx4rkIk1xyFHRlqI7&x5=1&f=json
这个两个API有些共同的参数:__biz,pass_ticket,公共参数可以通过抓包获取。
也有各自独有的参数:历史文章API中offset是一直变化的,appmsg_token也会随着时间失效,抓包可以获取appmsg_token,而offset是以0开始,可以通过API返回看到下一个offset是接口返回的字段“next_offset”值。


文章评论API中的appmsgid是具体文章的图文消息ID,comment_id也与具体文章相关,appmsg_token每篇文章也不同。通过文章链接获取源代码我们可以查看到文章评论API的三个参数comment_id,appmsgid,appmsg_token,如下图:

历史文章API返回的json信息:

下面是通过格式化后并删除一些不需要数据后的信息,json格式

 

文章评论API返回的json信息:

base_resp是返回状态情况,elected_comment才是评论的信息

elected_comment下面的详细信息,当评论有回复时,reply_list有信息

本文使用python3.6,pymysql连接mysql数据库,具体代码如下:

# -!- coding: utf-8 -!-
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#作者:cacho_37967865
#博客:https://blog.csdn.net/sinat_37967865
#文件:wechatArticleList.py
#日期:2018-12-08
#备注:通过Fiddler抓包,获取微信公众号历史文章信息和文章评论信息存储到mysql数据库表   
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''import requests
import json
import pymysql
from datetime import datetime
import reclass wechatArticle:def __init__(self,_biz,_pass_ticket,_appmsg_token,_cookie,_offset=0):self.offset = _offset       # 不同公众号不一样self.biz = _bizself.pass_ticket = _pass_ticketself.appmsg_token = _appmsg_tokenself.headers = {'cookie':_cookie,'User-Agent':'Mozilla/5.0 (Linux; Android 8.0; FRD-AL00 Build/HUAWEIFRD-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132'}self.db = pymysql.connect(host="localhost",user="root",password="123456",port=3306,use_unicode=True,#charset="utf8",database="sunshine")self.cursor = self.db.cursor()def get_article_list(self):offset = self.offsetwhile True:api = 'https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz={0}&f=json&offset={1}&count=10&is_ok=1&scene=126&uin=777&key=777&pass_ticket={2}&wxtoken=&appmsg_token={3}&x5=1&f=json'.format(self.biz, offset, self.pass_ticket, self.appmsg_token)resp = requests.get(api, headers=self.headers).json()print(type(resp), resp)  # 字典类型ret, status = resp.get('ret'), resp.get('errmsg')     # 状态信息if ret == 0 or status == 'ok':offset = resp['next_offset']general_msg_list = resp['general_msg_list']#print(type(general_msg_list),general_msg_list)    # json类型msg_list = json.loads(general_msg_list)['list']    # 先转化为字典类型再获取列表类型for msg in msg_list:comm_msg_info = msg['comm_msg_info']           # 字典类型,每次推送的消息(一次三篇)msg_id = comm_msg_info['id']                   # 推送消息的idpost_time = datetime.fromtimestamp(comm_msg_info['datetime'])     # 发布时间try:app_msg_ext_info = msg['app_msg_ext_info']  # 字典类型,文章信息(一次三篇)first_article_id = app_msg_ext_info['fileid']first_article_title = app_msg_ext_info['title']  # 本次推送的首条文章标题first_article_digest = app_msg_ext_info['digest']  # 本次推送的首条文章摘要first_article_url = app_msg_ext_info['content_url']self.get_article_detail(first_article_id,first_article_url)first_url = first_article_url.replace('amp;', '').split('&chksm')[0]self.article_to_mysql(msg_id, first_article_id, first_article_title, first_article_digest,first_url, post_time)multi_app_msg_item_list = app_msg_ext_info.get('multi_app_msg_item_list')for article in multi_app_msg_item_list:article_id = article['fileid']multi_article_title = article['title']multi_article_digest = article['digest']multi_article_url = article['content_url']self.get_article_detail(article_id,multi_article_url)multi_url = multi_article_url.replace('amp;', '').split('&chksm')[0]self.article_to_mysql(msg_id, article_id, multi_article_title, multi_article_digest,multi_url, post_time)except Exception as f:print(str(f))def get_article_detail(self,article_id,content_url):try:url = content_url.replace('amp;', '').replace('#wechat_redirect', '').replace('http', 'https')html = requests.get(url, headers=self.headers).text#print(html)except:print('获取评论失败' + content_url)else:str_comment = re.search(r'var comment_id = "(.*)" \|\| "(.*)" \* 1;', html)str_msg = re.search(r"var appmsgid = '' \|\| '(.*)'\|\|", html)   # 文章的idstr_token = re.search(r'window.appmsg_token = "(.*)";', html)if str_comment and str_msg and str_token:comment_id = str_comment.group(1)  # 评论id(固定)app_msg_id = str_msg.group(1)      # 票据id(非固定)appmsg_token = str_token.group(1)  # 票据token(非固定)# 缺一不可if comment_id and app_msg_id and appmsg_token:print("爬取评论的链接:" + url,html)self.get_article_comments(app_msg_id,comment_id,appmsg_token,article_id)def get_article_comments(self,app_msg_id,comment_id,appmsg_token,article_id):api = 'https://mp.weixin.qq.com/mp/appmsg_comment?action=getcomment&scene=0&__biz={0}&appmsgid={1}&idx=2&comment_id={2}&offset=0&limit=100&uin=777&key=777&pass_ticket={3}&wxtoken=777&devicetype=android-26&clientversion=2607033b&appmsg_token={4}&x5=1&f=json'.format(self.biz, app_msg_id, comment_id, self.pass_ticket, appmsg_token)resp = requests.get(api, headers=self.headers).json()ret, status = resp['base_resp']['ret'], resp['base_resp']['errmsg']if ret =='0' or status == 'ok':elected_comment = resp['elected_comment']for comment in elected_comment:content_id = comment.get('content_id') # 评论IDnick_name = comment.get('nick_name')  # 评论人昵称like_num = comment.get('like_num')     # 点赞comment_time = datetime.fromtimestamp(comment.get('create_time'))  # 评论时间content = comment.get('content')       # 评论内容#print("评论内容文章:",article_id,nick_name)self.comment_to_mysql(article_id,content_id,comment_time,nick_name,like_num,content)def create_article_table(self):sql1 = 'drop table if exists mnyd_article;'sql2 = 'create table mnyd_article(No INT(11) NOT NULL AUTO_INCREMENT,msg_id VARCHAR(15),article_id VARCHAR(15),post_time timestamp(2),title VARCHAR(200),digest VARCHAR(200),article_url varchar(300),PRIMARY KEY (No));'self.cursor.execute(sql1)self.cursor.execute(sql2)self.db.commit()def article_to_mysql(self,msg_id, article_id,title,digest,article_url,post_time):sql = "insert into mnyd_article(msg_id,article_id,title,digest,article_url,post_time) values('%s','%s','%s','%s','%s','%s')" % (msg_id,article_id,title, digest,article_url,post_time)try:# 使用 cursor() 方法创建一个游标对象 cursorself.cursor.execute(sql)except Exception as e:# 发生错误时回滚self.db.rollback()print(str(e))else:self.db.commit()  # 事务提交print('事务处理成功')def create_comment_table(self):sql1 = 'drop table if exists mnyd_comment;'sql2 = "create table mnyd_comment(No INT(11) NOT NULL AUTO_INCREMENT,article_id VARCHAR(15),content_id VARCHAR(20),comment_time timestamp(2),nick_name VARCHAR(50),like_num int,content varchar(1000),PRIMARY KEY (No)) COLLATE='utf8mb4_unicode_ci';"self.cursor.execute(sql1)self.cursor.execute(sql2)self.db.commit()def comment_to_mysql(self,article_id,content_id,comment_time,nick_name,like_num,content):sql = "insert into mnyd_comment(article_id,content_id,comment_time,nick_name,like_num,content) values('%s','%s','%s','%s','%i','%s')" % (article_id,content_id,comment_time, nick_name,like_num,content)try:# 使用 cursor() 方法创建一个游标对象 cursorself.cursor.execute(sql)except Exception as e:# 发生错误时回滚self.db.rollback()print(str(e))else:self.db.commit()  # 事务提交print('事务处理成功')if __name__ == '__main__':biz = 'MzIwNTc4NTEwOQ=='  # "码农有道公众号"   mnyd_article  mnyd_commentpass_ticket = 'ZS3nqLX1df5GhZ+zf/t0FYyf7Nfp52yUJ+PuyJUKvQtyln78R3QzBU21Xo528IE+'app_msg_token = '986_G0Sy%252FL2pNlAGA9PIXcqTRipxsKaGLurexidEyg~~'     # 历史文章wap_sid2 = 'CL3qgfIFElxMOFBzZ2dZOHQ1WTcxamRQLXUyMGFiU0tvNkZzUEJmRURhZmtJTkhLcEtYWU9rNm5WYmUtd29qd3Q3UmVqbmpZXzFxS21GMG13amVjM1NEaUVPajZNZG9EQUFBfjDH8K3gBTgNQAE='cookie = 'wxuin=1581282621; version=2607033b; pass_ticket={}; wap_sid2={}'.format(pass_ticket, wap_sid2)# 以上信息不同公众号每次抓取都需要借助抓包工具做修改wxarticles = wechatArticle(biz, pass_ticket, app_msg_token, cookie)wxarticles.create_article_table()         # 创建数据库表记录文章wxarticles.create_comment_table()         # 创建数据库表记录评论wxarticles.get_article_list()              # 开始爬取文章和评论

介绍一下上面的几个函数:
create_comment_table():创建存储评论的表,其中必须设置COLLATE='utf8mb4_unicode_ci',是为了确保能够存储特殊格式(mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。)的微信昵称到数据库。
get_article_list():获取历史文章的信息,存入到数据库,并且将文章id和文章链接传入到get_article_detail()函数
get_article_detail():根据get_article_list()函数传入的参数获取文章评论API的参数
get_article_comments():根据get_article_detail()函数传入的参数获取文章评论并存入到数据库

此外注意以下几个要点:
def __init__(self,_biz,_pass_ticket,_appmsg_token,_cookie,_offset=0) 初始带cookie的参数信息,_offset=0对参数初始化
历史文章和文章评论API 可以通过str.format()设置参数
历史文章返回中有字段'app_msg_ext_info',在2017年5月前的文章是没有的,所以使用try.. except..

这个时候我们已经获取到了需要的信息,后续就是对信息进行处理并转化为自己的东西。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/568590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】Python简介和Python解释器

计算机语言的种类非常的多,总的来说可以分成机器语言,汇编语言,高级语言三大类。 机器语言(二进制)→汇编语言→(前面两种语言是与硬件进行交互) →高级语言(面向过程语言(C语言)→面向对象语言&#xff09…

【Python】单线程异步多线程多进程实例

上一篇文章主要介绍了多任务场景下单线程异步、多线程、多进程如何选择,链接:多任务场景下单线程异步多线程多进程 这里主要通过三个实例去验证一下简单的多任务场景下,三种方式的耗时情况,假设有10个互不关联的10个任务 多进程版…

python及pycharm2018软件安装教程

python及pycharm2018软件安装教程 python 3.6.5及pycharm2018.1.1 Win版32/64位下载地址: https://pan.baidu.com/s/1KdECgnrARK4HubPeFSKCTw 密码:bwc5 Python及PyCharm简介: Python 是一种面向对象的解释型计算机程序设计语言。是纯粹的自由…

2059 - authentication plugin 'caching_sha2_password' -navicat连接异常问题解决

使用navicat 连接 mysql 8.0.11 报 "2059 - authentication plugin caching_sha2_password ..." 解决办法: 进入mysql命令行然后输入 ALTER USER root% IDENTIFIED WITH mysql_native_password BY root1;

【测试工具】在linux测试环境安装bug管理工具禅道

在我们测试中,为了方便管理测试流程,提交测试发现的bug,我们需要使用到bug管理工具。有些大公司可能会自己开发一些bug管理工具,但是我们也会用一些开源的bug管理工具,比如Bugzilla,Redmine,Tra…

【测试工具】在linux测试环境访问禅道数据库

上一篇文章我们介绍了如何在linux测试环境安装bug管理工具禅道,现在我们来介绍一下如何访问禅道的数据库,访问数据库有什么用呢?首先,我们可以更改我们安装后的管理系统的名称(改为自己公司名称)&#xff0…

在命令提示符(cmd)下怎样复制粘贴(详细版)

我们的命令提示符面板,不能选中复制。应该怎么办呢? 按照下面的方法即可解决 输入“cmd”,确认。 此时打开了cmd窗口,在图中位置右键选择“属性”。 4 在弹出的窗口中,勾选“快速编辑模式”。 5 复制方框1中的文字…

python各种库安装

1、安装django pip install django 安装成功测试:进入cmd--》输入python--》输入import django-->输入 django.get_version(),若正常显示则说明安装成功 2、更新pip python -m pip install --upgrade pip 3、安装pymysql pip install pymysql 出现错误&…

【工具】SecureCRT安装和注册

SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件。 SecureCRT支持SSH,同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的理想工具。通过…

Windows下如何查看某个端口被谁占用并强制关闭

一、查看那个端口被调用 我告诉大家一个方法,^_^。 1、 开始—->运行—->cmd,或者是windowR组合键,调出命令窗口; 2、输入命令:netstat -ano,列出所有端口的情况。在列表中我们观察被占用的端口&a…

【性能测试】性能测试的基础理论

转发自博客园贺满:https://www.cnblogs.com/puresoul/p/5456855.html ,有删减。 随着软件行业的快速发展,现代的软件系统越来越复杂,功能越来越多,测试人员除了需要保证基本的功能测试质量,性能也随越来越受…

MySQL 处理插入重主键唯一键重复值办法

本篇文章主要介绍在插入数据到表中遇到键重复避免插入重复值的处理方法,主要涉及到IGNORE,ON DUPLICATE KEY UPDATE,REPLACE;接下来就分别看看这三种方式的处理办法。 IGNORE 当使用INSERT语句向表中添加一些行数据并且在处理期间发生错误时,…

【性能测试】性能测试的基本流程

转发自博客园贺满:https://www.cnblogs.com/puresoul/p/5463477.html,有删减。 本文主要介绍下性能测试的基本流程,性能测试从实际执行层面来看,测试的过程一般分为这么几个阶段,如下图: 下面分别介绍下每个…

【性能测试】性能测试工具选择

转发自博客园贺满:https://www.cnblogs.com/puresoul/p/5503134.html,有删减。 本篇文章主要简单总结下性能测试工具的原理以及如何选型。性能测试和功能测试不同,性能测试的执行是基本功能的重复和并发,需要模拟多用户&#xff0…

【测试工具】禅道项目管理工具设置触发邮箱

禅道支持邮件提醒,当需求、任务、bug等发生变化的时候,可以发邮件提醒。 禅道提醒邮件默认通知范围(禅道9.8版本,可以在 后台-消息-设置中设置哪些动作需要发信): 1、Bug:指派给抄送 添加&#…

【性能测试】Linux系统监控-Top命令

前面转载的三篇文章主要介绍了性能测试的相关概念,其中有提到服务器,服务器的配置是性能测试中必须考虑的,而且性能测试中也必须监控服务器。 这篇文章主要介绍一下如何通过Linux服务器自带的top命令监控运行情况,以下是直接top命…

【性能测试】Linux系统监控-CPU信息

我们知道CPU对于服务器来说非常重要,下面我们从几个方面介绍linux服务器CPU相关信息: 先要理解以下几个概念: 1、一台物理机的物理CPU的个数 2、一个CPU上的核数 3、一个核上面支持的线程数 有下面的计算公式: 总核数 物理C…

【Linux】Linux简介以及 与UNIX区别

一直以来对Linux、Unix、linux内核、linux发行版的概念比较模糊,最近查找资料并经过自己的整理,主要总结了Linux和UNIX的区别和联系、内核和操作系统的关系、Linux操作系统和结构、发行版本CentOS介绍。 Linux 和 UNIX 的关系/区别 Linux 是一个类似 U…

【视频】视频文件格式和视频编码

我们经常在电脑、电视、手机或者其他终端产品看视频,我们对视频有个大概了解,比如清晰度、大小、视频类型等,但是对于视频内部结构我们应该一无所知,现在我们来一步一步解开视频的神秘面纱。 首先大家要清楚两个概念,视…

【文字识别】Python3使用百度AI进行文字识别

将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR)。可以实现OCR 的底层库并不多,目前很多库都是使用共同的几个底层OCR 库,或者是在上面进行定制。 Tesseract 是一个OCR 库,目前…