Python 之微信指数小程序数据抓取

Fiddler安装和设置

安装

Fiddler 安装包可以从这里获取,如果失效了可以自己网上找一个安装。

链接:https://pan.baidu.com/s/10tYQ-uL6HMddkOcIKnWEKQ?pwd=d1io 

然后就是点击安装就好了,没什么好多说的。

启用HTTPS捕获

进入软件界面,点击 Tools -> Options -> HTTPS 启用捕获 https 请求并解密。

证书信任

设置信任根证书,不然进行抓包捕获时,其他网页就访问不了了。

证书安装

有时候,如果证书安装不正确,可能导致抓取 https 失败。如果你发现上面已经设置以后,仍然抓取不到 https 的话,可以尝试使用工具重新生成证书。

可以下载 fiddlercertmaker.exe 自动生成证书,具体安装过程可参考:Fiddler死活抓不了HTTPS包解决办法_fiddler 抓包 itune 310 错误-CSDN博客

链接:https://pan.baidu.com/s/19G6aBHtxQU4ViSicWw2NOw?pwd=y3uh 

设置自动转发

设置指定 url 自动转发到本地,我这里是自动把请求转发到了我本地一个 Flask 搭建的服务,设置好以后进行保存(转发地址记得和你服务的地址保持一致)。

设置自动转发 https://search.weixin.qq.com/cgi-bin/wxaweb/wxindexfluctuations 的目的主要是为了获取数据请求参数中的 openid 和 search_key,因为我需要这两个请求参数去构造新的 body。

Unmatched requests passthrough 一定要勾选上——也就是不影响其他未匹配的请求

开启捕获

可以从 File -> Capture Traffic 开启捕获,也可以用 F12 快捷键开启捕获,当左下角有 Capturing 字样时,表示捕获已开启。

然后就可以正常捕获抓取 https 请求了

数据抓取处理

搭建并启动本地服务

可以自己在本地简单写一个服务接收和转发的请求并处理。我这里构造了两个 body 去分别获取 指数趋势数据来源

如果出现 Your proxy appears to only use HTTP and not HTTPS 报错,把转发 url 修改成 http 即可。

# coding:utf-8
import csv
import datetime
import json
import os
import tracebackimport pygal
from pygal.style import Styleimport requests
import urllib3
from flask import Flask, requestapp = Flask(__name__)time_indexes_map = {"time": "日期","score": "指数"
}channel_scores_map = {"finder_score": "视频号","live_score": "直播","mpdoc_score": "公众号","query_score": "搜一搜","extlink_score": "网页","ad_score": "其他","total_score": "总计","score_exp": "score_exp",  # 这个字段没找到对应中文意义,先以原始key值映射
}headers = {'Host': 'search.weixin.qq.com','Connection': 'keep-alive',# 'Content-Length': '182','xweb_xhr': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309092b) XWEB/9129','Content-Type': 'application/json','Accept': '*/*','Sec-Fetch-Site': 'cross-site','Sec-Fetch-Mode': 'cors','Sec-Fetch-Dest': 'empty','Referer': 'https://servicewechat.com/wxc026e7662ec26a3a/53/page-frame.html','Accept-Encoding': 'gzip, deflate, br','Accept-Language': 'zh-CN,zh;q=0.9',}# class ValueColors(pygal.style.Style):
#     value_colors = ("#f6c443", "#ff6146", "#7c160", "#4fadf8", "#a9e87a", "#eda150")class ResultHandler:def __init__(self, file_save_dir):self.file_save_dir = file_save_dirself._init_file_save_dir()def _init_file_save_dir(self):os.makedirs(self.file_save_dir, exist_ok=True)def draw_line(self, title, time_indexes, last_day=7):time_indexes = time_indexes[-last_day:]date_chart = pygal.StackedLine(fill=True, interpolate='hermite', x_label_rotation=-20, style=pygal.style.LightGreenStyle)date_chart.x_labels = [str(x["time"])[4:] for x in time_indexes]date_chart.add(title, [x["score"] for x in time_indexes])file_path = os.path.join(self.file_save_dir, "line.svg")date_chart.render_to_file(file_path)def draw_pie(self, title, channel_scores, last_day=7):# 颜色对应关系可以使用 pyautogui 的 getpixel 取色器获取# colors_map = {#     "ad_score": "#eda150",#     "extlink_score": "#a9e87a",#     "finder_score": "#f6c443",#     "live_score": "#ff6146",#     "mpdoc_score": "#7c160",#     "query_score": "#4fadf8"# }channel_scores = channel_scores[-last_day:]channel_score = channel_scores.pop()for cs in channel_scores:for key, score in cs.items():channel_score[key] += score# pie_chart = pygal.Pie(inner_radius=0.5, style=pygal.style.LightSolarizedStyle)pie_chart = pygal.Pie(inner_radius=0.5)pie_chart.title = title# print(channel_score)total_score = channel_score["total_score"]for key, score in channel_score.items():if key in ["score_exp", "total_score"]:continuepercent = float("{:.2f}".format(100 * score / total_score))pie_chart.add(channel_scores_map[key], percent)file_path = os.path.join(self.file_save_dir, "pie.svg")pie_chart.render_to_file(file_path)def write_csv(self, title, rows: list):if len(rows) == 0:return Truefieldnames = list(rows[0].keys())fieldnames = sorted(fieldnames, key=lambda x: len(x))file = title + "_" + datetime.datetime.now().strftime("%Y%m%d") + ".csv"file_path = os.path.join(self.file_save_dir, file)try:with open(file_path, 'w', newline='', encoding='utf-8') as f:writer = csv.DictWriter(f, fieldnames)if set(fieldnames) == set(time_indexes_map):writer = csv.DictWriter(f, time_indexes_map.keys())writer.writerow(time_indexes_map)elif set(fieldnames) == set(channel_scores_map):writer = csv.DictWriter(f, channel_scores_map.keys())writer.writerow(channel_scores_map)else:writer.writeheader()for row in rows:writer.writerow(row)except Exception as e:print(e)traceback.format_exc()return Falsereturn True@app.route('/post_data', methods=['POST'])
def post():if request.method == 'POST':today = datetime.datetime.now().strftime("%Y%m%d")file_save_dir = f"./files/{today}"result_handler = ResultHandler(file_save_dir)urllib3.disable_warnings()data = request.get_json()# print(data)openid = data.get("openid")search_key = data.get("search_key")query = [data.get("query")]end_ymd = datetime.datetime.now().strftime("%Y%m%d")start_ymd = (datetime.datetime.now() - datetime.timedelta(365)).strftime("%Y%m%d")# forward_url = 'https://search.weixin.qq.com/cgi-bin/wxaweb/wxindex'forward_url = 'http://search.weixin.qq.com/cgi-bin/wxaweb/wxindex'# 指数趋势json_data = {'openid': openid, 'search_key': search_key, 'cgi_name': 'GetDefaultIndex','query': query, 'compound_word': [], 'start_ymd': start_ymd, 'end_ymd': end_ymd}response = requests.post(forward_url, json=json_data, headers=headers, verify=False)response_data = response.json()# json.dump(response_data, open("test1.json", "w"), indent=2)title = response_data["content"]["resp_list"][0]["query"]time_indexes = response_data["content"]["resp_list"][0]["indexes"][0]["time_indexes"]print(time_indexes[:2])title_indexes = title + "_指数趋势"result_handler.draw_line(title_indexes, time_indexes, 30)result_handler.write_csv(title_indexes, time_indexes)# # 数据来源json_data2 = {'openid': openid, 'search_key': search_key, 'cgi_name': 'GetMultiChannel','query': query, 'start_ymd': start_ymd, 'end_ymd': end_ymd}response = requests.post(forward_url, json=json_data2, headers=headers, verify=False)response_data = response.json()# json.dump(response_data, open("test2.json", "w"), indent=2)result_list = response_data["content"]["result_list"]channel_scores = [c["channel_score"] for c in result_list]print(channel_scores[:2])title_scores = title + "_数据来源"result_handler.draw_pie(title_scores, channel_scores, 30)result_handler.write_csv(title_scores, channel_scores)return {}if __name__ == '__main__':app.run(host="127.0.0.1", debug=True)

小程序搜索关键字

  • 进入电脑端微信
  • 搜索 微信指数 小程序
  • 进入小程序,输入想要搜索的关键词(比如:和平精英)

数据图表展示

微信图表展示如下:

我们自己使用 pygal 画的图如下(svg 图用浏览器打开),对比发现,除了插值导致的光滑度不一样,图的整体走势是一致的:

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

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

相关文章

数据库设计实例---学习数据库最重要的应用之一

一、引言【可忽略】 在学习“数据库系统概述”这门课程时,我一直很好奇,这样一门必修课,究竟教会了我什么呢? 由于下课后,,没有拓展自己的眼界,上课时又局限于课堂上老师的讲课水平,…

【YOLOv10】2024年5月最新的YOLO系列模型Yolov10(论文阅读笔记) + 完整创新点说明 + 总结

🚀🚀🚀 YOLOv10: 实时端到端的目标检测。YOLOv10比最先进的YOLOv9延迟时间更低,测试结果可以与YOLOv9媲美,可能会成为YOLO系列模型部署的“新选择”。 官方论文地址:https://arxiv.org/pdf/2405.14458 官方…

[vue3后台管理二]首页和登录测试

[vue3后台管理二]首页和登录测试 1 修改main.js import ./assets/main.cssimport { createApp } from vue import App from ./App.vue import router from ./router createApp(App).use(router).mount(#app)2 路由创建 import {createRouter, createWebHistory} from vue-ro…

C++ 网络编程

一、Reactor 网络编程模型 reactor 是一个事件处理模型。网络处理:因为用户层并不知道 IO 什么时候就绪,所以将对 IO 的处理转化为对事件的处理。网络模型构成: 非阻塞 IO:操作 IO,如果 IO 未就绪,IO 函数会立刻返回。IO 多路复用:检测多路 IO 是否就绪。工作流程: 注册…

浅谈路由器转发数据包

当路由器转发数据包时,它会经历一系列步骤,包括接收数据包、路由表查询、以及转发数据包。以下是详细的步骤描述: 1. 接收数据包 以太网帧到达端口:当一个以太网帧到达路由器的某个网络接口(端口)时&#…

Django 做migrations时出错,解决方案

在做migrations的时候,偶尔会出现出错。 在已有数据的表中新增字段时,会弹出下面的信息 运行这个命令时 python manage.py makemigrationsTracking file by folder pattern: migrations It is impossible to add a non-nullable field ‘example’ to …

旧手机翻身成为办公利器——PalmDock的介绍也使用

旧手机有吧!!! 破电脑有吧!!! 那恭喜你,这篇文章可能对你有点用了。 介绍 这是一个旧手机废物利用变成工作利器的软件。可以在 Android 手机上快捷打开 windows 上的文件夹、文件、程序、命…

鸿蒙时间滑动选择器弹窗

例子: Button(打开弹窗).fontSize(14).width(106).height(32).padding({ left: 0, right: 0 }).fontColor(#999).onClick(()>{DatePickerDialog.show({selected:new Date(),onDateAccept:(value)>{AlertDialog.show({ message:JSON.stringify(value) })}})}) …

“Excel+中文编程”衍生新型软件,WPS用户:自家孩子

你知道吗,我们中国人有时候真的挺有创新精神的。 你可能熟悉Excel表格,也可能听说过中文编程,但你有没有脑洞大开,想过如果把这两者结合起来,会碰撞出什么样的火花呢? 别不信,跟着我来看看吧&a…

实时通信的方式——WebRTC

文章目录 基于WebRTC实现音视频通话P2P通信原理如何发现对方? 不同的音视频编解码能力如何沟通?(媒体协商SDP)如何联系上对方?(网络协商) 常用的API音视频采集getUserMedia核心对象RTCPeerConne…

raid配置与实战10

一、raid理论 1、raid概述 raid(磁盘阵列):是用不同的硬盘分区,组成一个逻辑上的硬盘,高可用(冗余)。 2、raid级别 2.1、raid0条带化存储 数据分散在多个物理磁盘上的存储方式,…

vue3学习(四)

前言 接上篇学习笔记&#xff0c;分享3个内置组件&#xff1a;动态组件、缓存组件、分发组件基本用法。大家一起通过code的示例&#xff0c;从现象理解,注意再次理解生命周期。 一、code示例 组件A&#xff1a;CompA <script setup> import {onMounted, onUnmounted} f…

linux Inodes满导致数据库宕机

项目经理反馈集群环境中有个节点无法使用了需要支援下&#xff0c;同时发过来截图说明磁盘还是有空的。 登录系统后直接发现问题 orcl2:/home/oracledb2> sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Wed May 29 13:59:21 2024 Copyright (c) 1982,…

民国漫画杂志《时代漫画》第32期.PDF

时代漫画32.PDF: https://url03.ctfile.com/f/1779803-1248635561-0ae98a?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

类的内存对齐位段位图布隆过滤器哈希切割一致性哈希

文章目录 一、类的内存对齐1.1规则1.2原因 二、位段2.1介绍2.2内存分配问题2.3跨平台问题2.4使用的注意事项 三、位图的应用3.1 给40亿个不重复的无符号整数&#xff0c;找给定的一个数。&#xff08;int的范围可以到达42亿多&#xff09;3.2 给定100亿个整数&#xff0c;设计算…

记录github小程序短视频系统的搭建过程

GitHub - lkmc2/AwesomeVideoWxApp: 《倾心短视频》微信小程序 这个项目按readme中的来可以部署成功&#xff0c;但是会发现图片、视频全是空的&#xff0c;如下图&#xff1a; 修改源代码&#xff0c;更换图片上传与保存地址 大概涉及到这些代码块&#xff0c;进行更改即可。…

Codeforces Round 948 (Div. 2) E. Tensor(思维题-交互)

题目 n(3<n<100)个点的有向图&#xff0c; 图的边的关系未知&#xff0c;但保证以下两点&#xff1a; 1. 只存在j->i&#xff08;i<j&#xff09;的边 2. 对于任意三个点i、j、k&#xff08;i<j<k&#xff09;&#xff0c;要么k可以到达i&#xff0c;要么…

开源数据库同步工具DBSyncer

前言&#xff1a; 这么实用的工具&#xff0c;竟然今天才发现&#xff0c;相见恨晚呀&#xff01;&#xff01;&#xff01;&#xff01; DBSyncer&#xff08;英[dbsɪŋkɜː]&#xff0c;美[dbsɪŋkɜː 简称dbs&#xff09;是一款开源的数据同步中间件&#xff0c;提供M…

如何使用 ArcGIS Pro 计算水库库容量

计算水库库容量可以在前期规划的时候协助水库的选址和预估水库的规模&#xff0c;这里为大家介绍一下在 ArcGIS Pro 中如何计算水库的库容量&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的DEM数据&#xff0c;除了DEM数据&#xff0c;常见…

opencascade AIS_Circle AIS_ColoredDrawer AIS_CameraFrustum 源码学习 圆

类AIS_Circle 构造圆形基准面&#xff0c;用于构建复合形状。 AIS_Circle() [1/2] AIS_Circle::AIS_Circle ( const Handle< Geom_Circle > & aCircle ) 初始化用于构造 AIS 圆形基准面的算法&#xff0c;并初始化圆形 aCircle。 AIS_Circle() [2/2] AIS_Circ…