这几天师父有个小项目,挺有意思,如何使用python爬微信公众号中的新闻信息。大体流程如下。图1:流程

其实我们看到,这里并没有想象中的“智能”——依然需要手动刷公众号文章,然后才能够收集到信息。(误:更新的第9部分是更加智能的操作,减少手刷)需要用到的工具:Python,Fiddler(附上下载地址)https://www.telerik.com/fiddler​www.telerik.com具体操作如下

1. 电脑下载fiddler图2:下载fiddler

2. 安装之后,点开第一眼看到的是这样图3:fiddler第一次点开之后

这里附上fiddler的介绍。https://www.cnblogs.com/zhaoyanjun/p/7068905.html​www.cnblogs.com

3. 设置由于我们只抓手机浏览信息,所以这里选择 from remote clients only(弹出来的提示都选Yes)。图4:设置Tools-Options-HTTPS

然后设置Actions:点击Actions,选择Trust root certificate以及export root certificate to desktop(弹出来的提示都选Yes)。图5:设置Actions由于是手机连接代理,所以勾选allow remote computers to connect ,记住8888这个数字(不同的电脑可能不同,弹出来的提示都选Yes)。图6:设置Tools-Options-Connections关闭Fiddler

4. 手机设置(我使用红米手机,其他手机大致一样)找到IP地址,电脑cmd中输入ipconfig,找到自己的ip地址,例如我的IP地址是192.168.124.14

手机连接和电脑一样的WiFi;

设置手机WiFi(手机“设置”中),在手机中修改“代理”的“主机名”(电脑中的ip地址192.168.124.14)以及“端口”(来自图6的fiddler listens on post的数字8888)。图7:设置手机WiFi代理(proxy)在手机浏览器中输入网址:192.168.124.14:8888(主机名+Port),前往下载FiddlerRoot Certificate。图8:手机进入网址192.168.124.14:8888图9:点击FiddlerRoot Certificate图10:下载之后安装它,随意命名,我命名为“Fiddler2”

5. 重启电脑的Fiddler,手机点开公众号文章,电脑Fiddler收集信息图11中的序号5~20是我在手机点开微信公众号的文章之后、电脑Fiddler记录的信息。其中HTTPS的信息最为关键。如果没有这类信息的记录,建议返回上面看看,看看是哪一步出错了。图11:记录分析某一条记录观察图12 的序号16,左边查看“json”+“HTTPS”+“mp.weixin.qq.com”的提示信息,右边查看“inspectors”+“headers”中的“miscellaneous”中的“refrerer”中的网址。这个网址就是微信公众号的最终链接,也是我们要收集的链接。图12:具体分析可以复制这条链接,在网页中打开,的确是刚刚在手机打开的公众号的文章。图13:复制Fiddler记录的链接,在浏览器中点开过滤注意观察到,微信公众号所有的信息都是以“mp.weixin.qq.com”开头,因此这里通过Filter将其单独过滤出来。图14:过滤重启Fiddler,在手机中不断点开公众号的文章,fiddler记录如下。图15:过滤之后的信息

可以看到,序号存在着跳跃,因为过滤起到了作用。

6. 将所有信息导出全选之后,右击,选择“Save”-“selected sessions”-“as text”图16:导出手机浏览记录该txt中记录了所有的浏览网址信息,建议另存为utf-8格式,便于Python读取。图17:txt信息

7. Python抽取公众号信息抽取txt中的链接

import numpy as np

data = []

with open(r'...\1_Full.txt', 'r', encoding='utf-8') as fp:

for line in fp:

if 'Referer: https://mp.weixin.qq.com/' in line: //将含有重要信息的链接保留到data中

data.append(line[9:])

// 去重

data = np.unique(data)网页结构抓取,待完善

8. 通过电脑微信客户端抓取公众号的信息

在一遍一遍刷手机之后,本人务必厌烦。。如果能够通过鼠标点击电脑为内心客户端,然后通过fiddler收集信息,那么就不用刷手机了。。注意,在调整fiddler的时候,anaconda的jupyter关闭(可以使用spyder),否则fiddler会出问题。

操作差不多。

首先,将fiddler-Tools-Options-HTTPS,将Decrypt HTTPS traffic修改为“from all processes”.图18:电脑收集微信公众号的操作

然后,同样在自己的浏览器中,输入IP地址+8888,下载证书。图19:下载FiddlerRoot证书

下载之后进行安装。图20:安装证书

其他设置filter和上面手机设置一样,都是把关于wp.weixin的内容筛选出来。

然后,刷电脑端微信公众号,那么filter就能够记录下所有的公众号文章。注意,一旦打开fiddler,那么电脑无法访问其他网页,因为百度等防爬机制很严格,会检测到fiddler已经启动。

9. 更加自动和智能的操作

无论是刷手机收集信息,还是通过电脑端刷公众号,依然是需要人点击信息,不够智能。这里在参考了新的案例之后,能够进行颠覆性的改进

首先,本文前面的模块依然需要了解。当已经能够在电脑端刷微信公众号的文章、同时fiddler能够收集https的信息,那么继续往下。以“首都之窗”微信公众号为例。

(1)电脑微信端的操作

打开fiddler。

点击设置-通用设置-使用系统默认浏览器打开网页。图21:电脑微信端设置

然后,随意点击“首都之窗”的任意一篇文章,会在浏览器中弹出来。放在那里,不用理会。顺便把fiddler中记录的这个文章信息删了。留着fiddler空白,记录第25图的重点内容!

这一步的目的是为了能够顺利在浏览器中打开公众号的历史消息并且刷新。图22:先点一篇文章图23:该文章在浏览器弹出来图24:完整操作

接着,进入“首都之窗”公众号,点击查看历史消息。图25:查看历史消息

同样,“历史消息”在浏览器(绝不能在微信客户端下拉、因为fiddler收不到信息)中弹出来,然后往下开始刷几下,需要看到有新的内容弹出来,同时看到fiddler正在记录更新的信息。fiddler更新的消息就是最重要的内容。图26:在浏览器中下拉几次“历史消息”

(2)fiddler信息分析

刚刚通过在浏览器下拉公众号历史消息,fiddler采集到了更新的信息。我们开始分析。图27:分析因为下拉历史消息而收集到的某一条记录

选择第8条记录(该记录来自浏览器中下拉历史记录而收集到的消息),重点部分已经在headers中圈出来了。

(3)链接分析(看不下去的话,直接看代码怎么拼出链接)

分析这个链接。可以看到,它是由几个部分组成。

①http://mp.weixin.qq.com/mp/profile_ext?②action=getmsg ③&__biz=MzA5NDY5MzUzMQ== ④&f=json⑤&offset=20 ⑥&count=10 ⑦&is_ok=1 ⑧&scene=124 ⑨&uin=777 ⑩&key=777 ⑪&pass_ticket= ⑫&wxtoken= ⑬&appmsg_token=1052_D6g2L7mM%252BaKLoVQK33V8q4D4wk3doi7QeR3Zog~~⑭&x5=0&f=json HTTP/1.1

那么我们需要关注的信息是:

③__biz:公众号的id(公众号的biz唯一),⑤offset:翻页标志,⑬appmsg_token:某个有时效性的token(隔一段时间会变化)

我们再看下面几个链接

GET /mp/profile_ext?action=getmsg&__biz=MzA5NDY5MzUzMQ==&f=json&offset=40&count=10&is_ok=1&scene=124&uin=777&key=777&pass_ticket=&wxtoken=&appmsg_token=1052_D6g2L7mM%252BaKLoVQK33V8q4D4wk3doi7QeR3Zog~~&x5=0&f=json HTTP/1.1

GET /mp/profile_ext?action=getmsg&__biz=MzA5NDY5MzUzMQ==&f=json&offset=60&count=10&is_ok=1&scene=124&uin=777&key=777&pass_ticket=&wxtoken=&appmsg_token=1052_D6g2L7mM%252BaKLoVQK33V8q4D4wk3doi7QeR3Zog~~&x5=0&f=json HTTP/1.1

biz和appmsg_token一致,offset改变,即为新的一页。因此,第一步,我们已经找到了翻页的规律。链接中只有这三个在变化,其他没有变动。因此,链接在python中能够写成:

api = 'https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz={0}&f=json&offset={1}&count=10&is_ok=1&scene=124&uin=777&key=777&pass_ticket=&wxton=&appmsg_token={2}&x5=0&f=json HTTP/1.1'.format(

__biz, offset, appmsg_token)

(4)cookie和headers

cookie保存的是微信登录的信息,在爬虫的时候需要填进去。我们只要关注wsp_sid2的cookies信息。

cookies同样来自图27。找到wap_sid2=CK6vyK4CElxLdmda............

headers同样来自图27。找到 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362"

(5)爬取

好的,以上找到了很多信息。初步的python如下:

import requests

import json

# 链接拼接三个信息

__biz = "MzA5NDY5MzUzMQ=="

appmsg_token = "1052_D6g2L7mM%252BaKLoVQK33V8q4D4wk3doi7QeR3Zog~~"

offset = 20

# cookies和headers

cookies = "wap_sid2=CK6vyK4CElxLdmda......."

headers = {'Cookie':cookies,

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362"

}

# api拼出来

api = 'https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz={0}&f=json&offset={1}&count=10&is_ok=1&scene=124&uin=777&key=777&pass_ticket=&wxton=&appmsg_token={2}&x5=0&f=json HTTP/1.1'.format(

__biz, offset, appmsg_token)

# 抓取并且json化

resp = requests.get(api, headers = headers, verify=False).json()

为什么需要把resp进行json化?我们可以尝试着打开9(3)一开始的链接的网页,图28:拼出来的api打开的网页长这样

很明显这是个json信息。因此需要json化。复制该网页的全部文本,放在http://json.cn网页中,可以看到完整的json结构。这就是resp的网页结果。图29:把图28的文本信息复制放在json.cn中的结果

那么resp在python中被json化之后的结果如下图30:resp在python中的结构

(6)网页解析

接下来,关注该resp的结构以及一层一层分析。图30中resp中errmsg=ok和ret=0,均表示网页可以正常打开(如果报错的话,ret=-3)。next_offset是下一次翻页的标志,需要保存起来。

next_offset = resp.get('next_offset')

general_msg_list = resp.get('general_msg_list')

# 将general_msg_list转为json格式

msg_list = json.loads(general_msg_list)['list']

general_msg_list 是 重要的内容。点击general_msg_list,这依然是一个json结构。图31:general_msg_list依然是json结构。

复制里面的文本,放到http://json.cn中看看是什么。图32:general_msg_list放到json.cn中的结果

因此被json化之后的msg_list,在python中长这样图33:把general_msg_list进行json化在python中的样子

可以看到,msg_list中含有10个记录。我们抽出一个记录,进行具体分析。在分析之前,我们要明确一个东西。msg_list中包含了10个记录,不是指10篇文章,而是10次推送。某一次公众号推送消息,可能同时发布好几条文章,也有可能是一篇文章。因此,要明白,单个msg记录,是指一个推送(and可能一次性发布了好几篇文章)。图34:某一次推送,一起发布了3篇文章

msg = msg_list[0]图35:某一个具体的msg

该msg里面包含了“app_msg_ext_info”和“comm_msg_info”两个内容。在http://json.cn中,这两个内容分别长这样子。图36:某一个msg具体的两部分---app_msg_ext_info和comm_msg_info

那么comm_msg_info包含了该推送的基本信息:推送ID,时间等。

app_msg_ext_info是什么?且听我慢慢分析。首先,title,digest一直到is_multi,都是该次推送的打头文章(就是图34中带图片的那个文章的信息)。例如title标题/digest关键词/content_url链接/source_url原链接等。

is_multi是判断该次推送是不是有读篇文章;=1表示yes,=0表示no。那么这里等于1,说明该次推送还有其他文章,存在于multi_app_msg_item_list中。

把multi_app_msg_item_list取出来。

multi_app_msg_item_list = app_msg_ext_info.get('multi_app_msg_item_list')图37:该推送剩下的两篇文章藏在multi_app_msg_item_list中

到目前为止,我们已经分析完了整体的流程。

总结图38:总结如何走出第一步图39:具体分析结构

(7)具体代码如下

import requests

import json

from datetime import datetime

import pandas as pd

import time

class WxMps:

def __init__(self, biz, appmsg_token, cookies, offset, city):

self.biz = biz

self.msg_token = appmsg_token

self.offset = offset

self.headers = {'Cookie':cookies, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'

}

self.city = city

def parse1(self, resp):

# 控制下一个抓取的offset

offset = resp.get('next_offset')

# 将包含主要内容的list转为json格式

general_msg_list = resp.get('general_msg_list')

# 一个msg_list中含有10个msg

msg_list = json.loads(general_msg_list)['list']

df1 = pd.DataFrame(columns = ['msg_id', 'post_time', 'msg_type', 'title', 'cover', 'author', 'digest', 'source_url', 'content_url'])

# 循环message列表

for msg in msg_list:

# msg是该推送的信息,包含了comm_msg_info以及app_msg_ext_info两个信息,注意某一个推送中可能含有多个文章。

comm_msg_info = msg.get('comm_msg_info')

app_msg_ext_info = msg.get('app_msg_ext_info')

# 该推送的id

msg_id = comm_msg_info.get('id')

# 该推送的发布时间,例如1579965567需要转化为datetime,datetime.fromtimestamp(1579965567)

post_time = datetime.fromtimestamp(comm_msg_info['datetime'])

# 该推送的类型

msg_type = comm_msg_info.get('type')

if app_msg_ext_info:

# 推送的第一篇文章

title, cover, author, digest, source_url, content_url = self.parse2(app_msg_ext_info)

df2 = self.df_process(msg_id, post_time, msg_type, title, cover, author, digest, source_url, content_url)

df1 = pd.concat([df1, df2])

# 判断是不是多篇文章

is_multi = app_msg_ext_info.get("is_multi")

# 如果是1,继续爬取;如果是0,单条推送=只有一篇文章

if is_multi:

multi_app_msg_item_list = app_msg_ext_info.get('multi_app_msg_item_list')

for information in multi_app_msg_item_list:

(title, cover, author, digest, source_url, content_url) = self.parse2(information)

df2 = self.df_process(msg_id, post_time, msg_type, title, cover, author, digest, source_url, content_url)

df1 = pd.concat([df1, df2])

return df1, offset

def start(self):

offset = self.offset

df1 = pd.DataFrame(columns = ['msg_id', 'post_time', 'msg_type', 'title', 'cover', 'author', 'digest', 'source_url', 'content_url'])

while offset <= 30: # 自行修改

print(offset)

api = 'https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz={0}&f=json&offset={1}&count=10&is_ok=1&scene=124&uin=777&key=777&pass_ticket=&wxton=&appmsg_token={2}&x5=0&f=json HTTP/1.1'.format(

self.biz, offset, self.msg_token)

resp = requests.get(api, headers = self.headers, verify=False).json()

time.sleep(10)

# ret 和 status 判断能不能继续抓取

ret, status = resp.get('ret'), resp.get('errmsg')

if ret == 0 or status == 'ok':

print("Crawling : ok")

print("\n")

print("\n")

df2, offset = self.parse1(resp)

df1 = pd.concat([df1, df2])

df1['city'] = self.city

else:

print("Before break, offset with problem is%d"%offset)

break

return df1

def parse2(self, info):

title = info.get('title')

cover = info.get('cover')

author = info.get('author')

digest = info.get('digest')

如何用python爬取公众号文章_Python+fiddler:爬取微信公众号的文章相关推荐

  1. python write非法字符报错_Python爬虫实现的微信公众号文章下载器

    平时爱逛知乎,收藏了不少别人推荐的数据分析.机器学习相关的微信公众号(这里就不列举了,以免硬广嫌疑).但是在手机微信上一页页的翻阅历史文章浏览,很不方便,电脑端微信也不方便. 所以我就想有什么方法能否 ...

  2. python 下载公众号文章_Python爬虫实现的微信公众号文章下载器

    平时爱逛知乎,收藏了不少别人推荐的数据分析.机器学习相关的微信公众号(这里就不列举了,以免硬广嫌疑).但是在手机微信上一页页的翻阅历史文章浏览,很不方便,电脑端微信也不方便. 所以我就想有什么方法能否 ...

  3. python信息检索和评价系统_Python爬虫实现的微信公众号文章下载器

    所以我就想有什么方法能否将这些公众号文章下载下来.这样的话,看起来也方便.但是网上的方法要么太复杂(对于我这个爬虫入门新手来说),要么付费. 但我的需求其实却很简单--"方便的查找 / 检索 ...

  4. 微信公众号数据2019_全国公众号总排名2019,全国微信公众号排名

    全国公众号总排名2019,全国微信公众号排名 公众号排名优化的注意事项及细节今天给大家分享一下,作为微信公众号的排名优化对于大多数人来说都已经知道了有这个渠道的事情,其实很多的新产品及渠道出来以后有不 ...

  5. 微信公众号数据2019_微信公众号榜单排名,2020微信公众号排名

    微信公众号榜单排名,2020微信公众号排名 公众号排名优化的注意事项及细节今天给大家分享一下,作为微信公众号的排名优化对于大多数人来说都已经知道了有这个渠道的事情,其实很多的新产品及渠道出来以后有不少 ...

  6. 微信公众号Java开发-笔记01【微信公众号介绍、开发环境搭建】

    学习网址:哔哩哔哩网站 微信公众号开发-Java版 微信公众号Java开发-笔记01[微信公众号介绍.开发环境搭建] 微信公众号Java开发-笔记02[] 微信公众号Java开发-笔记03[] 微信公 ...

  7. 微信公众号 php sdk,GitHub - yuanchenglu/wechat-php-sdk: 微信公众平台 PHP SDK

    微信公众平台 PHP SDK 介绍 简单的微信公众平台 PHP SDK ,通过调用相应的接口,使你可以轻松地开发微信 App .测试方法如下: Clone 或下载项目源码,上传至服务器. 进入微信公众 ...

  8. 微信公众号怎么推送消息_微信公众号发送消息

    A.模板消息发送 模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等.不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息. 备注 ...

  9. 微信公众号答题怎么做_分享微信公众号在线答题系统使用方法

    微信公众号在线答题系统注意事项,微信公众号在线答题系统虽然制作简单,但是有几个地方特别要注意一下,不然会出错的.其一:题库题目的数量,一定要确保题库数 > (每天答题数*活动天数) .其二,微信 ...

  10. 微信公众号是html页面吗,微信公众号怎么使用页面模板功能?微信公众号页面模板功能怎么使用?...

    软件大小: 56.0 MB 软件版本: 4.0.0 软件类型: 文本处理 查看详情 直接下载 yesky 标签: 微信公众号怎么使用页面模板功能?微信公众号页面模板功能怎么使用?微信公众号后台推出了& ...

最新文章

  1. Python培训分享:python如何用cookie实现自动模拟登录?
  2. xilinx IP核之ROM
  3. matlab中有哪些有趣的命令?好玩的matlab彩蛋
  4. java的socket读取一行就结束运行了?使用这种方法可以读取多行数据!
  5. idea 暂存文件或idea切换分支代码不见了
  6. HDU 5136 Yue Fei's Battle
  7. 在Vim中将DOS行尾转换为Linux行尾
  8. yarn 常用命令(干干货!)
  9. 最快的 java 图像_java – 最快的性能过滤图像
  10. WMS——新能源汽车减速机组装工厂WMS案例
  11. cass道路设计教程_cass道路曲线设计
  12. 绘制正方形图形(C语言)
  13. matlab 图片序列与视频互转(来源于matlab官网)
  14. cmd脚本(WIN10下)
  15. 中国平安产险总经理易人 吴鹏已获保监会核准
  16. 单点登录 SSO 解决方案选型指南|身份云研究院
  17. oss客户端工具_云享会 | 沃云公有云重点产品推荐:文件存储NASamp;对象存储OSS...
  18. 2022年会发生全球经济危机吗?很可能会!
  19. SpringBoot入门:项目下载,依赖,启动
  20. 水果音乐制作软件的安装教程

热门文章

  1. 大学计算机汉字字形码,计算机处理汉字信息的前提条件是对每个汉字进行编码...
  2. winRAR真难用,我决定自创一个(炼虚期) 文件的压缩与解压 将色色一网打尽
  3. Pytorch手动更新梯度报错解决方法
  4. 【poi第七节】poi设置excel 设置字体格式,java设置excel设置字体格式
  5. ICML 2017 paper
  6. 3.3、云计算FusionAccess桌面组件介绍与安装
  7. 万能ExpandableListAdapter适配器
  8. mysql sqlstate 42000_MySQL SQL Error: 1064, SQLState: 42000 错误
  9. stm32 电磁巡线小车
  10. ORACLE Docker容器云试用