Python(一)實現一個爬取微信小程序數據的爬蟲+工程化初步實踐

文章目錄

  • 前言
  • 用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;請設…