文章目录

  • 前言
  • 用Charles 抓包 iOS 微信小程序
    • 在Mac端和iOS端安装Charles 自签名证书
      • Mac端
      • iOS端
    • 能抓到Safari浏览器的包但是抓不到微信小程序的包
    • 直接在iOS 上抓包的App
    • 如何抓取Android 7.0 以上/Harmony OS微信小程序包
  • Python 项目工程化
    • pip 切换为国内镜像源
    • 工程化参考
      • 脚手架
    • Python 虚拟环境
  • 实现爬虫
    • 动态IP
      • 确保代理服务器的延迟够低
    • 设置User-Agent
    • 发起爬虫请求
      • 设置请求的证书
      • 关闭其他科学上网工具
      • 使用多线程提高并发
    • 推送爬取结果到iOS
    • 未解决的问题
      • 打码平台破解验证码
  • 备注

前言

公司准备用Python替换传统的Shell来做自动化运维,最近正好在做这方面的code review,试着用Python写一个小爬虫,顺便入门一下Python。

该爬虫的功能是:

  1. 对目标小程序定时发起下订单请求
  2. 将下订单请求结果推送到iOS以提醒成功或失败

用Charles 抓包 iOS 微信小程序

原理是:电脑和手机处于同一网络中,在电脑上安装Charles,电脑和手机都安装Charles 自签名证书,然后更改手机网络设置,将手机上的网络请求转发至电脑上的Charles以实现抓包

在Mac端和iOS端安装Charles 自签名证书

Mac端

设置步骤见Charles 文档 > SSL Certificates > MacOS部分。

  1. 安装完毕 在 钥匙串访问 中设置为始终信任
    在这里插入图片描述
  2. 在 Proxy > SSL Proxy Settings > Include 中添加任意域名 ,然后在浏览器中访问该网站来测试 Charles是否可以解析HTTPS数据包。如果想对所有流量进行抓包,域名设置为*, 端口设置为443,不过不建议这样做,这样做会有大量的我们不关心的包,会对我们造成干扰。这种做法建议只用于测试配置是否正确

iOS端

设置步骤见Charles 文档 > SSL Certificates > iOS 部分 。

  1. 在iOS 浏览器中下载且安装完证书之后,在设置 > 通用 > 关于本机 > 证书信任设置 中启用该证书
  2. 修改网络设置 > 配置代理 > 手动 > IP (可以在Charles > Help > Local IP Address 中找到),Port 一般为8888
  3. 打开浏览器 访问任意网站,注意:这里要和Charles 中的 SSL Proxy Settings > Include 对应。查看Charles是否可以解析HTTPS数据

能抓到Safari浏览器的包但是抓不到微信小程序的包

经过上面的测试之后,开始正式抓小程序的包。 Mac端和iOS端 的浏览器都可以抓到包,不过却发现无法抓小程序的包。 Google了一下发现,需要打开 设置 > App > 微信 > 本地网络

感谢这位博主的分享

直接在iOS 上抓包的App

为什么会有这个需求呢?是因为 我觉得在iOS上抓包这么做太麻烦了,想着有没有直接可以安装在iOS上的App,还真有

  1. Charles iOS版,58 人民币,还未购买使用
  2. Stream,免费。但是经过实际测试,该App已经很久没更新了,无法抓HTTPS包
  3. 蜻蜓抓包,免费。未经过测试使用

如果还有其他好用的iOS抓包 App,欢迎评论区留言推荐

如何抓取Android 7.0 以上/Harmony OS微信小程序包

在另一台华为手机 微信中抓包发现抓不到,系统为harmony os 4.2。Google了一下,发现很多人都有这个问题。简单来说,在 Android7.0 及以上的系统中,App只信任系统预装证书而不信任用户安装的证书。由于主力机是iPhone,我就没有深入研究如何解决这个问题,想解决这个问题可参考 知乎回答 和 另外一位博主分享

Python 项目工程化

经过上面的抓包,拿到了目标小程序的请求格式和数据格式。开始写Python脚本,既然是个项目,不如从一开始就规范起来,使用企业级的Python项目工程化结构,包括:使用流行的包管理工具,代码风格,代码风格检测,单元测试,打包等等

pip 切换为国内镜像源

最好切换为国内镜像源,这样下载包更快更稳定。

我使用清华大学的镜像源

pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
pip config set global.trusted-host mirrors.tuna.tsinghua.edu.cn

工程化参考

关于Python项目的工程化我使用的python项目工程化指南里提到的一些组件,建议阅读该指南并学习其中 快速上手 章节的小例子

脚手架

  1. 上述指南中使用的脚手架是cookiecutter,如果你也使用,需要在初始化好之后升级一些依赖的版本,脚手架生成的一些依赖的版本现在比较低了,如果直接使用会报错
  2. cookiecutter 的提交信息提示已经是5年前了,另外一个比较活跃的脚手架项目是pyscaffold。我还没研究,等后面研究透了再在其他博文中详细介绍。

本文使用的cookiecutter

Python 虚拟环境

Python虚拟环境推荐使用poetry。激活Python项目的虚拟环境命令见poetry > Managing environments文档

实现爬虫

根据上述指南生成项目脚手架且升级了相关依赖之后,开始正式写爬虫代码。核心爬虫逻辑就几行,构造下订单数据,然后使用requests发起请求

动态IP

在测试过程中,发现目标小程序添加了同一个IP 1秒内不能访问2次的限制。找了一家国内付费的TLS代理服务的公司,买了个IP池。国内付费HTTP/TLS代理的公司对于个人用户推出的套餐基本差不多,有按照数量计费的,有按照小时/天计费的。我选的是按数量计费并且所选IP失效为5分钟左右。

在选择具体产品时要关注

  1. IP得是 高度匿名代理,这样才不会被目标服务器追踪到原始客户端IP
  2. IP质量,代理IP要够稳定且延迟低

确保代理服务器的延迟够低

要让代理请求到目标小程序的延迟够低,首先选择的IP最好和目标小程序所在区域一样。经过上面的抓包,得知小程序的域名,使用dig命令通过域名查到该域名的IP

dig www.xxxx.com

再通过IP归属地查询得知,该小程序部署在阿里云 > 华北区域 > 青岛

在接入HTTP代理服务时,商家一般提供可选城市,选择离青岛最近的城市即可。

当然了还要综合考量,不一定离目标网站所在地越近的代理IP速度越快,应该还和商家自身的硬件部署有关,所以如果发现离目标网站所在地的IP反而更慢,那就果断切换至其他节点

即使完成了上述步骤,商家给你的IP池不一定每一个延迟都很低,所以在拿到IP之后,要测试一下该IP到目标小程序的速度,如果速度不满足则丢弃重新获取新的IP,重复上述步骤直至获得满足延迟的IP

"""get low latency proxy servers"""
import json
import logging
import timeimport requestslogger = logging.getLogger(__name__)PROXY_SERVICE_PROVIDER_URL = ("这里是HTTP代理服务商家的接入API")
TARGET_SERVER_URL = "这里是目标小程序的API"def get_proxy_ips_latency_less_than_one_second(need_ip_nums: int) -> dict:"""return a set of ip latency less than 1 second"""good_proxy_ip = {}request_start_time = time.time()proxy_index = 1while len(good_proxy_ip) < need_ip_nums :reponse = requests.get(PROXY_SERVICE_PROVIDER_URL, timeout=5)logger.debug(json.dumps(reponse.json(), indent=4, ensure_ascii=False))ip = reponse.json()["data"][0]["ip"]port = reponse.json()["data"][0]["port"]proxy_ip = f'http://{ip}:{port}'proxies = {"http": proxy_ip,"https": proxy_ip}if test_proxy_delay(proxies, TARGET_SERVER_URL, 1):good_proxy_ip[proxy_index] = proxiesproxy_index += 1request_end_time = time.time()logger.info("successfully get a batch of proxy IPs with a delay""of less than or equals 1 second, cost %d seconds", request_end_time - request_start_time)logger.info("IP proxies:\n%s", good_proxy_ip)return good_proxy_ip
def test_proxy_delay(request_proxies, target_url: str, request_timeout: int) -> bool:"test proxy ip's latency whether less than timeout seconds"request_start_time = time.time()logger.debug("start time: %s", time.strftime("%H:%M:%S", time.localtime(request_start_time)))# add try-except block to avoid program crashestry:response = requests.get(target_url, timeout=5, proxies=request_proxies)if response.status_code == 200 and response.json().get("code") == 200 and response.json().get("msg") == "操作成功":request_end_time = time.time()logger.debug("end time: %s", time.strftime("%H:%M:%S", time.localtime(request_end_time)))delay = request_end_time - request_start_timelogger.debug("Proxy %s response time: %.2f seconds", request_proxies, delay)return  delay <= request_timeoutreturn Falseexcept requests.exceptions.RequestException as e:logger.error("Error testing proxy %s: %s", request_proxies, str(e))return False

设置User-Agent

伪造 User-Agent,使用fake-useragent。使用该库时注意,多次请求/多线程 应只使用同一个对象,避免多次初始化对象浪费时间

ua = UserAgent(platforms='mobile')
ua.random

发起爬虫请求

最终在发起请求时,设置reqeusts的proxies即可

response = requests.post(request_url,request_json_data, headers=request_header,timeout=5, verify=CERT_PATH, proxies=request_proxies)

设置请求的证书

分两种情况

  1. 如果你想在请求过程中开着Charles,这时的证书来自Charles。把Charles的证书保存下来,这时CERT_PATH是Charles自己证书的路径。Charles 官方文档 > Python 提到了这一点
  2. 如果你已经抓到了所需要的目标小程序的数据格式,那么请求时无需再开Charles代理。这时的证书来自 浏览器打开 目标小程序 域名 > 查看证书 > 下载 。下载前点击证书详情,并确保这个证书的名字不带有Charles,如果有,则关闭Charles并在浏览器中 删除目标小程序的cookie,重新加载,即可获得小程序后台服务器的证书

关闭其他科学上网工具

有的科学上网工具,如果你没设置好,无论国内国外的流量都会先经过它的节点,这样请求反而是慢了很多

使用多线程提高并发

我这里还没有使用scheduler,只是使用 threading.Thread方法。线程的执行逻辑是,线程启动之后,即准备数据,即

  1. 获得一个延迟足够低的代理IP
  2. 构造请求数据
  3. 在requests.post前一行计算当前时间距离目标时间的毫秒数,然后time.sleep 休眠。等到目标时间一到,所有线程立刻同时发起请求而无需等待其他步骤

推送爬取结果到iOS

由于该爬虫是定时执行,有的时候不一定在家。所以需要一个将爬取结果推送到iOS上。

鉴于APNs即Apple Push Notification service 有点复杂且不想花时间在上面,于是使用Bark来帮助快速开发。接入步骤非常简单,建议阅读文档

未解决的问题

经过上述步骤,mini版的爬虫基本满足了自己的需求,即定时下单并推送消息到iOS提醒我付款。但是有以下几个问题未解决

  1. token 失效和刷新机制尚不清楚且获取token的请求我也没找到。导致每次真正爬取之前都要验证下token是否失效,如果失效了,还得重新抓取请求获得有效token
  2. 该小程序防止爬虫请求只在用户ID层面制订了防护策略,即只允许同一用户下两单,并没有接入验证码之类的防护

打码平台破解验证码

如果未来该小程序接入了验证码,那么我决定使用付费的打码平台来进行破解。

有关打码平台的介绍,可参考打码平台是如何高效的破解市面上各家验证码平台的各种形式验证码的? 这篇文章

备注

由于该爬虫足够简单,就不再提供示例源码。有关Python的其他最佳实践日后会在其他博文中介绍,本篇只是让各位同学对Python工程化和基本的爬虫技术有个整体的了解

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

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

相关文章

uview ui request get / post 传参含params和json数据的分析和使用

背景。单独写了controller方法去配合移动端的接口调用。但有的接口与pc端类似。于是进行了复用。但接口得复制不是。 uview js request 文档 注意迪三个参数是header 后端接口GET方法 调用代码截图 浏览器调试 总结。 复制之前的api接口。为了方便复用底层实现。接口类型…

用 pnpm + TurboRepo,构建多项目高效开发体系

在现代前端项目日益复杂的今天&#xff0c;我们越来越多地面对一个场景&#xff1a;多个项目共享逻辑、组件和依赖&#xff0c;而维护和构建效率却在不断拉垮。这种情况下&#xff0c;传统项目结构的痛点就显现无遗。 从我亲身实践来看&#xff0c;选择 pnpm TurboRepo 构建 …

Pytest 使用命令行参数执行指定环境的脚本—— Python 实践

&#x1f9fe; 一、项目背景 在自动化测试中&#xff0c;我们经常需要根据不同的运行环境&#xff08;如测试环境和生产环境&#xff09;来执行测试脚本。本文将详细介绍如何通过命令行参数来指定运行环境&#xff0c;并使用 Python 和 pytest 框架实现这一功能。 &#x1f6e…

利用可控验证码位数实现拒绝服务攻击(DoS)风险与线程模型分析

一、背景介绍&#xff1a;验证码接口中的潜在 DoS 漏洞 在渗透测试过程中&#xff0c;常见验证码接口支持传入“验证码位数”参数&#xff0c;表面看是业务可配置&#xff0c;实则若未做上限控制&#xff0c;极易成为资源消耗型 DoS 攻击入口。 &#x1f9ea; 测试场景&#…

Spring Cloud Feign 整合 Sentinel 实现服务降级与熔断保护

Spring Cloud Feign 整合 Sentinel 实现服务降级与熔断保护 在微服务架构中&#xff0c;服务之间的调用往往依赖 Feign&#xff0c;而服务调用的稳定性又至关重要。本文将介绍如何将 Feign 与 Sentinel 结合使用&#xff0c;实现服务的容错保护&#xff08;如降级与熔断&#…

宠物医院系统的设计与实现(springBoot版)

一、开题报告 一、本选题研究的意义和背景&#xff08;理论与现实意义&#xff09;&#xff1a; 背景&#xff1a;随着人们生活水平的提高&#xff0c;宠物饲养愈发普遍&#xff0c;宠物医院的需求也日益增长。挂号方式主要依赖现场挂号&#xff0c;导致宠物主人需要长时间排队…

SOCKSv5 协议通信的完整阶段与报文格式详解

SOCKSv5 协议的通信通常分为以下几个主要阶段&#xff1a; 方法协商阶段 (Method Negotiation)方法依赖的子协商阶段 (Method-Dependent Sub-negotiation) - 本例为用户名/密码认证请求发送阶段 (Request Sending)请求回复阶段 (Request Reply)数据传输阶段 (Data Transfer) …

​​Git提交代码Commit消息企业级规范

​​Git Commit 类型完整指南​​ 类型用途示例​​feat​​新增功能&#xff08;面向用户的功能性变更&#xff09;git commit -m "feat: 添加用户登录功能"​​fix​​修复 Bug&#xff08;解决代码中的问题&#xff09;git commit -m "fix: 修复首页加载崩溃…

TiDB AUTO_RANDOM 超大主键前端精度丢失排查:JavaScript Number 限制与解决方案

前端长整型主键“失踪”记 ——一次 ArrayIndexOutOfBoundsException 的排查全过程 一、事故现场 最近在维护 SMS-OFFICE 后台系统时&#xff0c;运维同事反馈&#xff1a; 点击「短信详情」或「邮箱账号详情」时&#xff0c;偶尔弹窗空白、日志报错&#xff1a; java.lang.A…

在postgresql使用mybatis动态创建数据库分区表

在postgresql使用mybatis动态创建数据库分区表 1. 整体描述2. 前期准备2.1 创建主表语句2.2 创建分表语句2.3 xxl-job 3. 代码实现3.1 mapper.xml层3.2 mapper.java层3.3 service接口层3.4 service实现层3.5 controller层 4. 总结 1. 整体描述 在java下实现&#xff1a;创建分…

Python网安-zip文件暴力破解

目录 源码在这里 需要的模块 准备一个密码本和需要破解的ZIP文件 一行一行地从密码文件中读取每个密码。 核心部分 注意&#xff0c;需要修改上段代码注释里的这段具有编码问题的代码&#xff1a; 源码在这里 https://github.com/Wist-fully/Attack/tree/cracker 需要的…

聊聊Golang开发工程师

诞生背景 Go由Google三位顶尖工程师&#xff08;Ken Thompson、Rob Pike、Robert Griesemer&#xff09;设计&#xff0c;目标是解决两大行业痛点&#xff1a; 硬件利用率不足&#xff1a;多核CPU普及&#xff0c;但C/C等语言难以高效利用并发能力&#xff1b; 开发效率低下&a…

机器学习6——线性分类函数

线性分类函数 分类问题的两种决策方法&#xff1a; 概率方法&#xff1a;通过计算后验概率进行分类。优点是在概率分布已知的情况下可以得到最优解&#xff0c;缺点是实际中概率密度通常未知&#xff0c;需要通过大量数据估计。判别方法&#xff1a;假设判别函数的形式已知&…

Sentinel(三):Sentinel熔断降级

一、Sentinel熔断概念介绍 官方文档网址&#xff1a;circuit-breaking | Sentinel 1、Sentinel熔断基本介绍 除了流量控制以外&#xff0c;对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措 施之一。一个服务常常会调用别的模块&#xff0c;可能是另外的一个远程服…

PostgreSQL 主从集群搭建

下面是 PostgreSQL 主从复制&#xff08;Streaming Replication&#xff09;环境的安装与配置指南&#xff0c;适合在两台或多台服务器之间构建一主一从&#xff08;或一主多从&#xff09;的高可用读写分离系统。 环境准备 角色主机名/IP说明主库192.168.1.10可读写&#xff…

STM32安全固件升级:使用自定义 bootloader 实现SD卡固件升级,包含固件加密

前言 在 STM32 嵌入式开发中&#xff0c;Bootloader 是一个不可或缺的模块。ST 公司为 STM32 提供了功能完备的官方 Bootloader&#xff0c;支持多种通信接口&#xff08;如 USART、USB DFU、I2C、SPI 等&#xff09;&#xff0c;适用于标准的固件更新方案。 然而&#xff0c…

一步部署APache编译安装脚本

接下来我来介绍以下编译安装的好处 编译安装的优点与缺点 一、优点 高度可定制 可根据实际需求启用或关闭特性&#xff08;如 Apache 的模块、MySQL 的引擎等&#xff09;。 灵活控制编译参数、优化性能&#xff08;如 --enable-xxx、--with-xxx&#xff09;。 更高的性能…

[Linux]mmap()函数内存映射原理及用法

一、内存映射 内存映射&#xff0c;简而言之就是将用户空间的一段内存区域映射到内核空间&#xff0c;映射成功后&#xff0c;用户对这段内存区域的修改可以直接反映到内核空间&#xff0c;同样&#xff0c;内核空间对这段区域的修改也直接反映用户空间。那么对于内核空间和用…

通信无BUG,ethernet ip转profinet网关,汽车焊接设备通信有心机

在运用“激光钎焊”对汽车车顶、侧面板、后行李箱盖等位置进行接合时&#xff0c;必须配备能够沿着复杂车身线条&#xff0c;对细窄焊接线实施高精度快速检测及模仿控制的“焊缝跟踪控制”。 那么汽车生产线的系统升级改造迫在眉睫&#xff0c;当西门子PLC和库卡机器人无法通信…

python脚本ETH获取最新发行版本并将是否更新信息发送到钉钉

import requests import json import time import hmac import hashlib import base64 import urllib.parse# 1. 配置钉钉机器人 webhook "https://oapi.dingtalk.com/robot/send?access_tokenXXX" secret "XXX" # 如果没有加签验证&#xff0c;请设…