爬蟲筆記20——票星球搶票腳本的實現

以下內容僅供交流學習使用!!!

思路分析

前面的爬蟲筆記一步一步走過來我們的技術水平也有了較大的提升了,現在我們來進行一下票星球搶票實戰項目,實現票星球的自動搶票。

  1. 我們打開票星球的移動端頁面,分析每一步操作需要用到的接口。
  2. 先手動操作搶票找到搶票流程的每一個接口后,判斷接口請求要求,請求方式,以及是否需要傳遞什么參數。
  3. 接下來就是每個接口一步一步操作請求響應,然后成功返回200即可。
  4. 然后實現過程主要是創建一個類對象,配置需要用到的屬性,每一步操作封裝成每一個函數,最后用一個主函數運行。
  5. 當然,下面是代碼的大體內容,主要講解如何操作,需要全部代碼可以找一下我發布的資源下載。

示例代碼

首先我們要用到下面三個包,pip下載即可

#pip install requests fake_useragent datetime
#請求
import requests
#隨機UA
from fake_useragent import UserAgent
#時間
import datetime

然后我們創建一個類對象,初始化方法里面創建需要用到的屬性變量:

class PXQ:def __init__(self):# 輸入自己的tokenself.token = '這里要打開網頁開發者工具找到你自己的token'# 演唱會項目id,必填,最簡單就是在url上可以看到,下面這個是要操作搶購的演唱會的show_id# 或者也是打開網頁開發者工具中的網絡也是可以找到self.show_id = '665708481d06bc0001627d83'# 指定場次id,不指定則默認從第一場開始遍歷,查找同理self.session_id = '665708656a025300012ae72a'# 購票數量,自行設置要購買的數量,但一定要看購票須知,不要超過上限self.buy_count = 1# 指定觀演人,觀演人序號從0開始,人數需與票數保持一致self.audience_idx = [0]# audience_idx = [0]# 門票類型,不確定則可以不填,讓系統自行判斷。快遞送票:EXPRESS,電子票:E_TICKET/ID_CARD,現場取票:VENUE,電子票或現場取票:VENUE_E,目前只發現這四種,如有新發現可補充self.deliver_method = ''# 獲取想要購買的票價idself.seat_plan_id = ''self.session_id_exclude = []  # 被排除掉的場次self.price: int = 0# 搶購的票價名稱self.seatPlanName = ''self.threadsLists = []# 判斷是否對應價位有票數,默認是無self.flag = False# 設置搶票開始時間,自行設置開搶時間,分別是年月日時分秒self.startTime = datetime.datetime(2024, 7, 3, 2, 0, 0)# 隨機UAself.user_agent = UserAgent()

接下來就是操作流程每個請求接口設置,封裝成方法,依次是:

  • 根據項目id獲取所有場次和在售狀態
    # 根據項目id獲取所有場次和在售狀態def get_sessions(self, useragent):headers = {'User-Agent': useragent,'Content-Type': 'application/json'}url = "https://m.piaoxingqiu.com/cyy_gatewayapi/show/pub/v3/show/" + self.show_id + "/sessions_dynamic_data"response = requests.get(url=url, headers=headers).json()if response["statusCode"] == 200:# 獲取場次的id# print(response)return response["data"]["sessionVOs"]else:print("get_sessions異常:" + str(response))return None
  • 根據場次id獲取座位信息,箭頭后面表示函數返回數據類型
    def get_seat_plans(self, useragent) -> list:headers = {'User-Agent': useragent,'Content-Type': 'application/json'}url = "https://m.piaoxingqiu.com/cyy_gatewayapi/show/pub/v3/show/" + self.show_id + "/show_session/" + self.session_id + "/seat_plans_static_data"response = requests.get(url=url, headers=headers).json()if response["statusCode"] == 200:# 查看票價的id# print(response)return response["data"]["seatPlans"]else:raise Exception("get_seat_plans異常:" + str(response))
  • 獲取座位余票
# 獲取座位余票def get_seat_count(self, useragent) -> list:headers = {'User-Agent': useragent,'Content-Type': 'application/json'}url = "https://m.piaoxingqiu.com/cyy_gatewayapi/show/pub/v3/show/" + self.show_id + "/show_session/" + self.session_id + "/seat_plans_dynamic_data"response = requests.get(url=url, headers=headers).json()if response["statusCode"] == 200:return response["data"]["seatPlans"]else:raise Exception("get_seat_count異常:" + str(response))
  • 獲取門票類型(快遞送票EXPRESS,電子票E_TICKET,現場取票VENUE,電子票或現場取票VENUE_E)
# 獲取門票類型(快遞送票EXPRESS,電子票E_TICKET,現場取票VENUE,電子票或現場取票VENUE_E)def get_deliver_method(self, useragent, qty: int) -> str:headers = {'User-Agent': useragent,'Content-Type': 'application/json','access-token': self.token}data = {"items": [{"skus": [{"seatPlanId": self.seat_plan_id,  "sessionId": self.session_id,  "showId": self.show_id,  "skuId": self.seat_plan_id,"skuType": "SINGLE","ticketPrice": self.price, "qty": qty  #數量}],"spu": {"id": self.show_id,"spuType": "SINGLE"}}]}url = "https://m.piaoxingqiu.com/cyy_gatewayapi/trade/buyer/order/v3/pre_order"response = requests.post(url=url, headers=headers, json=data).json()if response["statusCode"] == 200:# 這里的print可以去掉# print(response["data"]["supportDeliveries"][0])return response["data"]["supportDeliveries"][0]["name"]else:raise Exception("獲取門票類型異常:" + str(response))
  • 獲取觀演人信息
# 獲取觀演人信息# def get_audiences() -> list | None:def get_audiences(self, useragent):headers = {'User-Agent': useragent,'Content-Type': 'application/json','access-token': self.token}url = "https://m.piaoxingqiu.com/cyy_gatewayapi/user/buyer/v3/user_audiences"response = requests.get(url=url, headers=headers).json()if response["statusCode"] == 200:# 可以獲取觀影人的信息查看是否正確return response["data"]else:print("get_audiences異常:" + str(response))return None
  • 提交訂單需要做的判斷比較多,要判斷演出票是什么票型(快遞送票EXPRESS,電子票E_TICKET/ID_Card,現場取票VENUE,電子票或現場取票VENUE_E)
# 提交訂單(快遞送票EXPRESS,電子票E_TICKET/ID_Card,現場取票VENUE,電子票或現場取票VENUE_E)def create_order(self, useragent, qty: int, express_fee: int,receiver, cellphone, address_id, detail_address, location_city_id, audience_ids: list):headers = {'User-Agent': useragent,'Content-Type': 'application/json','access-token': self.token}if self.deliver_method == "EXPRESS":data = {"priceItemParam": [{"applyTickets": [],"priceItemName": "票款總額","priceItemVal": self.price * qty,"priceItemType": "TICKET_FEE","priceItemSpecies": "SEAT_PLAN","direction": "INCREASE","priceDisplay": "¥" + str(self.price * qty)},{"applyTickets": [],"priceItemName": "快遞費","priceItemVal": express_fee,"priceItemId": self.show_id,"priceItemSpecies": "SEAT_PLAN","priceItemType": "EXPRESS_FEE","direction": "INCREASE","priceDisplay": "¥" + str(express_fee)}],"items": [{"skus": [{"seatPlanId": self.seat_plan_id,"sessionId": self.session_id,"showId": self.show_id,"skuId": self.seat_plan_id,"skuType": "SINGLE","ticketPrice": self.price,"qty": qty,"deliverMethod": self.deliver_method}],"spu": {"id": self.show_id,"spuType": "SINGLE"}}],"contactParam": {"receiver": receiver,  # 張三"cellphone": cellphone  # 13812345678},"one2oneAudiences": [{"audienceId": i, "sessionId": self.session_id} for i in audience_ids],"addressParam": {"address": detail_address,  # 星巴克咖啡門口"district": location_city_id[4:],"city": location_city_id[2:4],"province": location_city_id[0:2],"addressId": address_id}}elif self.deliver_method == "ID_CARD":data = {"priceItemParam": [{"applyTickets": [],"priceItemName": "票款總額","priceItemVal": self.price * qty,"priceItemType": "TICKET_FEE","priceItemSpecies": "SEAT_PLAN","direction": "INCREASE","priceDisplay": "¥" + str(self.price * qty),}],"items": [{"skus": [{"seatPlanId": self.seat_plan_id,"sessionId": self.session_id,"showId": self.show_id,"skuId": self.seat_plan_id,"skuType": "SINGLE","ticketPrice": self.price,"qty": qty,"deliverMethod": self.deliver_method,}],"spu": {"id": self.show_id, "spuType": "SINGLE"},}],"one2oneAudiences": [{"audienceId": i, "sessionId": self.session_id} for i in audience_ids],"many2OneAudience": {"audienceId": audience_ids[0],"sessionIds": [self.session_id],},}# 電子票已解決elif self.deliver_method == "E_TICKET":data = {"priceItemParam": [{"applyTickets": [],"priceItemName": "票款總額","priceItemVal": self.price * qty,"priceItemType": "TICKET_FEE","priceItemSpecies": "SEAT_PLAN","direction": "INCREASE","priceDisplay": "¥" + str(self.price * qty)}],"items": [{"skus": [{"seatPlanId": self.seat_plan_id,"sessionId": self.session_id,"showId": self.show_id,"skuId": self.seat_plan_id,"skuType": "SINGLE","ticketPrice": self.price,"qty": qty,"deliverMethod": self.deliver_method}],"spu": {"id": self.show_id,"spuType": "SINGLE"}}],"many2OneAudience": {"audienceId": audience_ids[0],"sessionIds": [self.session_id]}}elif self.deliver_method == "VENUE":data = {"priceItemParam": [{"applyTickets": [],"priceItemName": "票款總額","priceItemVal": self.price * qty,"priceItemType": "TICKET_FEE","priceItemSpecies": "SEAT_PLAN","direction": "INCREASE","priceDisplay": "¥" + str(self.price * qty)}],"items": [{"skus": [{"seatPlanId": self.seat_plan_id,"sessionId": self.session_id,"showId": self.show_id,"skuId": self.seat_plan_id,"skuType": "SINGLE","ticketPrice": self.price,"qty": qty,"deliverMethod": self.deliver_method}],"spu": {"id": self.show_id,"spuType": "SINGLE"}}],"one2oneAudiences": [{"audienceId": i, "sessionId": self.session_id} for i in audience_ids]}elif self.deliver_method == "VENUE_E":data = {"priceItemParam": [{"applyTickets": [],"priceItemName": "票款總額","priceItemVal": self.price * qty,"priceItemType": "TICKET_FEE","priceItemSpecies": "SEAT_PLAN","direction": "INCREASE","priceDisplay": "¥" + str(self.price * qty)}],"items": [{"skus": [{"seatPlanId": self.seat_plan_id,"sessionId": self.session_id,"showId": self.show_id,"skuId": self.seat_plan_id,"skuType": "SINGLE","ticketPrice": self.price,"qty": qty,"deliverMethod": self.deliver_method}],"spu": {"id": self.show_id,"spuType": "SINGLE"}}]}else:raise Exception("不支持的deliver_method:" + str(self.deliver_method))url = "https://m.piaoxingqiu.com/cyy_gatewayapi/trade/buyer/order/v3/create_order"response = requests.post(url=url, headers=headers, json=data).json()if response["statusCode"] == 200:print("下單成功!請盡快支付!")else:raise Exception("下單異常:" + str(response))
  • 主函數,前面都是函數定義,主要是在主函數執行操作搶票。
  • 我們前面已經知道哪個演唱會show_id,以及哪個場次session_id,現在要在主函數里面的seat_plan_id進行自行賦值,也可以開頭初始化方法里面賦值/默認為空,seat_plan_id可以通過前面get_seat_plans函數里的接口地址獲取。
# 主函數def main(self):# 創建隨機的useragentuseragent = self.user_agent.randomwhile True:try:# 獲取座位余票信息,默認從最低價開始seat_plans = self.get_seat_plans(useragent)# print(seat_plans)seat_count = self.get_seat_count(useragent)# print(seat_count)# 獲取想要購買的票價idself.seat_plan_id = '667ba34a090ca100015604df'# 提取出對應的票價for temp in seat_plans:if temp["seatPlanId"] == self.seat_plan_id:self.price = temp["originalPrice"]self.seatPlanName = temp["seatPlanName"]break# 判斷對應的票價id是否有剩余票數for i in seat_count:if i["seatPlanId"] == self.seat_plan_id:if i["canBuyCount"] > 0:self.flag = True# print(f'{self.seatPlanName}該價位剩余數量:可滿足您的購買需求')breakelse:self.flag = False# print(f'{self.seatPlanName}無剩余!')breakif self.flag:print(f'{self.seatPlanName}該價位剩余數量:可滿足您的購買需求')print('正在努力搶購中……')else:print(f'{self.seatPlanName}票價無剩余!,將繼續為你刷新搶購')continueif not self.deliver_method:self.deliver_method = self.get_deliver_method(useragent, self.buy_count)print("演唱票類型:" + self.deliver_method)if self.deliver_method == "VENUE_E":self.create_order(useragent, self.buy_count, 0, None, None, None, None, None, [])else:# 獲取觀演人信息audiences = self.get_audiences(useragent)if len(self.audience_idx) == 0:self.audience_idx = range(self.buy_count)audience_ids = [audiences[i]["id"] for i in self.audience_idx]if self.deliver_method == "EXPRESS":# 獲取默認收貨地址address = self.get_address(useragent)address_id = address["addressId"]  # 地址idlocation_city_id = address["locationId"]  # 460102receiver = address["username"]  # 收件人cellphone = address["cellphone"]  # 電話detail_address = address["detailAddress"]  # 詳細地址# 獲取快遞費用express_fee = self.get_express_fee(useragent, self.buy_count, location_city_id)self.create_order(useragent, self.buy_count, express_fee["priceItemVal"], receiver,cellphone, address_id, detail_address, location_city_id, audience_ids)elif self.deliver_method == "VENUE" or self.deliver_method == "E_TICKET" or self.deliver_method == "ID_CARD":self.create_order(useragent, self.buy_count, 0, None, None, None, None, None, audience_ids)else:print("不支持的deliver_method:" + self.deliver_method)breakexcept Exception as e:print(e)

以上內容全是定義在一個類中,我們要使用那就要創建一個類對象,現在我們打開一個文件入口進行創建:

if __name__ == '__main__':# 創建對象pxq = PXQ()while True:now = datetime.datetime.now()# 判斷當前時間與設置的開搶時間,并進行倒計時,當當前時間大于開搶時間直接開搶if now < pxq.startTime:print(f"{int(pxq.startTime.timestamp()-now.timestamp())}秒后開搶", end="\r")else:pxq.main()break

執行前我們配置好show_id,session_id和seat_plan_id,運行起來根據你設置的搶購時間在等待搶購的:
在這里插入圖片描述

獲取seat_plan_id的流程操作:
在這里插入圖片描述
搶票成功會顯示:
在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39589.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39589.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39589.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

視頻字幕提取在線工具有哪些?總結5個字幕提取工具

平時在沉浸式追劇的時候&#xff0c;我們常常都會被影視劇中的各種金句爆梗而逗得開懷大笑~而真正要用到時候卻總是一片頭腦空白。其實要記住它們最好的辦法便是將其提取留檔下來&#xff0c;每次有需要的時候打開就能一下子回顧到~ 今天就來帶大家盤一盤視頻字幕提取的軟件好…

高考假期預習指南

人不走空 &#x1f308;個人主頁&#xff1a;人不走空 &#x1f496;系列專欄&#xff1a;算法專題 ?詩詞歌賦&#xff1a;斯是陋室&#xff0c;惟吾德馨 目錄 &#x1f308;個人主頁&#xff1a;人不走空 &#x1f496;系列專欄&#xff1a;算法專題 ?詩詞歌…

目標檢測YOLO實戰應用案例100講-基于深度學習的無人機影像小目標識別

目錄 前言 研究現狀 深度學習研究現狀 目標檢測研究現狀 目標檢測存在的問題 2 基于深度學習的目標檢測算法理論基礎 2.1 卷積神經網絡 2.1.1 卷積層 2.1.2 池化層 2.1.3 激活函數 2.1.4 全連接層 2.2 優化器 2.3 基于深度學習的目標檢測算法 2.3.1 …

樹上差分的公式推導

今天寫了一道題目&#xff0c;需要采用線段樹合并樹上差分來解決 題目鏈接&#xff1a;P1600 [NOIP2016 提高組] 天天愛跑步 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) 其實當時已經想到要用這兩種方法&#xff0c;但苦于一直找不到轉移方程&#xff0c;最后看了答案才領…

java中可變參數

在Java中&#xff0c;... 是可變參數&#xff08;varargs&#xff09;的語法&#xff0c;用于允許一個方法接受可變數量的參數。可變參數的引入使得方法調用更加靈活和簡潔。以下是對可變參數的詳細解釋和使用示例。 可變參數的定義和使用 定義&#xff1a; 在方法參數列表中…

22-Pandas日期時間格式化

Pandas日期時間格式化 當進行數據分析時&#xff0c;我們會遇到很多帶有日期、時間格式的數據集&#xff0c;在處理這些數據集時&#xff0c;可能會遇到日期格式不統一的問題&#xff0c;此時就需要對日期時間做統一的格式化處理。比如“Wednesday, June 6, 2020”可以寫成“6…

Rust: polars行遍歷,從dataframe到struct及Bar設計比較

pandas提供了iterrows()、itertuples()、apply等行遍歷的方式&#xff0c;還是比較方便的。 polars的列操作功能非常強大&#xff0c;這個在其官網上有詳細的介紹。由于polars底層的arrow是列存儲模式&#xff0c;行操作效率低下&#xff0c;官方也不推薦以行方式進行數據操作。…

react_后臺管理_項目

目錄 1.運行項目 2. 項目結構 ①項目頂部導航欄 ②項目左側導航欄 ③主頁面-路由切換區 本項目使用的是 reacttsscss 技術棧。 1.運行項目 在當前頁面頂部下載本項目&#xff0c;解壓后使用編輯器打開&#xff0c;然后再終端輸入命令&#xff1a; npm i 下載依賴后&am…

【應急響應】Windows應急響應 - 基礎命令篇

前言 在如今的數字化時代&#xff0c;Windows系統面對著越來越復雜的網絡威脅和安全挑戰。本文將深入探討在Windows環境下的實戰應急響應策略。我們將重點關注實際應急響應流程、關鍵工具的應用&#xff0c;以及如何快速準確地識別和應對安全事件。通過分享實際案例分析&#…

FIO壓測磁盤性能以及需要注意的問題

一、壓測類型 1、順序讀&#xff08;IO&#xff09;&#xff1a;read&#xff0c;bs1M&#xff0c;job數從1開始往上加&#xff1a;2、3、4... 2、順序寫&#xff08;IO&#xff09;&#xff1a;write&#xff0c;bs1M&#xff0c;job數從1開始往上加&#xff1a;2、3、4... …

如何通過 1688 商品詳情的 API 接口獲取商品的詳細信息

在當今數字化商業的大背景下&#xff0c;能夠從 1688 這樣規模龐大且商品種類豐富的電商平臺中準確、高效地獲取商品的詳細信息&#xff0c;對于眾多企業和開發者而言&#xff0c;具有舉足輕重的意義。而通過 1688 商品詳情的 API 接口來實現這一目標&#xff0c;無疑是一種強大…

【ACM出版,馬來西亞-吉隆坡舉行】第四屆互聯網技術與教育信息化國際會議 (ITEI 2024)

作為全球科技創新大趨勢的引領者&#xff0c;中國不斷營造更加開放的科技創新環境&#xff0c;不斷提升學術合作的深度和廣度&#xff0c;構建惠及各方的創新共同體。這是對全球化的新貢獻&#xff0c;是構建人類命運共同體的新貢獻。 第四屆互聯網技術與教育信息化國際學術會議…

【 木蘭寬松許可證】

木蘭寬松許可證&#xff0c; 第1版 2019年8月 http://license.coscl.org.cn/MulanPSL 您對“軟件”的復制、使用、修改及分發受木蘭寬松許可證&#xff0c;第1版&#xff08;“本許可證”&#xff09;的如下條款的約束&#xff1a; 定義 “軟件”是指由“貢獻”構成的許可在“本…

【C++知識點總結全系列 (07)】:模板與泛型編程詳細總結與分析

模板與泛型編程 1、概述(1)What&#xff08;什么是模板、泛型編程&#xff09;(2)Why(3)Which(4)模板參數A.WhatB.HowC.模板參數的類型成員D.默認模板參數 2、模板函數3、模板類(1)How&#xff08;如何定義和使用模板類&#xff09;(2)成員模板 4、模板實參推斷(1)What&#xf…

入侵檢測模型

入侵檢測模型&#xff08;Intrusion Detection Model&#xff09;在網絡安全中起著至關重要的作用。它們用于識別和響應未經授權的訪問和攻擊行為。以下是常見的入侵檢測模型的詳細介紹&#xff1a; 一、入侵檢測模型分類 基于簽名的入侵檢測模型&#xff08;Signature-Based …

昇思25天學習打卡營第7天|Pix2Pix實現圖像轉換

文章目錄 昇思MindSpore應用實踐基于MindSpore的Pix2Pix圖像轉換1、Pix2Pix 概述2、U-Net架構定義UNet Skip Connection Block 2、生成器部分3、基于PatchGAN的判別器4、Pix2Pix的生成器和判別器初始化5、模型訓練6、模型推理 Reference 昇思MindSpore應用實踐 本系列文章主要…

大數據面試題之Flink(3)

如何確定Flink任務的合理并行度? Flink任務如何實現端到端一致? Flink如何處理背(反)壓? Flink解決數據延遲的問題 Flink消費kafka分區的數據時flink件務并行度之間的關系 使用flink-client消費kafka數據還是使用flink-connector消費 如何動態修改Flink的配置&a…

實戰:基于Java的大數據處理與分析平臺

實戰&#xff1a;基于Java的大數據處理與分析平臺 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討如何利用Java構建高效的大數據處理與分析平臺。…

Python基礎003

Python流程控制基礎 1.條件語句 內置函數input a input("請輸入一段內容&#xff1a;") print(a) print(type(a))代碼執行的時候遇到input函數&#xff0c;就會等鍵盤輸入結果&#xff0c;已回車為結束標志&#xff0c;也就時說輸入回車后代碼才會執行 2.順序執行…

pandas數據分析(5)

pandas使用Numpy的np.nan代表缺失數據&#xff0c;顯示為NaN。NaN是浮點數標準中地Not-a-Number。對于時間戳&#xff0c;則使用pd.NaT&#xff0c;而文本使用的是None。 首先構造一組數據&#xff1a; 使用None或者np.nan來表示缺失的值&#xff1a; 清理DataFrame時&#xf…