python使用requests秒殺茅臺(適用某寶,也可搶購其他商品)

專注的阿熊 發表於 2023-01-12
Python

import re, time, random, datetime, sys, requests, threading, psutil

from requests.cookies import RequestsCookieJar

from selenium.webdriver.common.by import By

from multiprocessing import Queue

from urllib.parse import quote

from selenium import webdriver

from io import BytesIO

from PIL import Image

class Login():

     def __init__(self):

         # 設定關鍵詞進行匹配或判斷,下同

         self.key_word1 = ' 賬號管理 '

         self.key_word2 = ' 安全連結 '

         self.j = 0

         # 建立佇列存放 post 訂單結果

         self.queue = Queue(maxsize=100)

         # 建立 Session 物件   requests 庫的 session 物件會在同一個 session 例項的所有請求之間使用 cookies 保持登入狀態

         self.session = requests.session()

         # 設定 headers

         ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.50"

         self.headers = {

             'User-Agent': ua

         }

         self.session.headers.update(self.headers)

     # 掃碼登入,獲取 cookies

     def get_cookies(self):

         options = webdriver.ChromeOptions()

         options.add_experimental_option('excludeSwitches', ['enable-logging'])

         options.add_argument('--headless')

         browser = webdriver.Chrome(options=options)

         url = '

         browser.get(url)

         # 點選跳轉掃碼介面

browser.find_element(By.XPATH,'/html/body/div[1]/div[2]/div[3]/div/div/div/div[1]/i').click()

         time.sleep(round(random.uniform(1,2),2))

         # 獲取並儲存二維碼截圖

         qrcode_img_data=browser.find_element(By.XPATH, '//*[@id="login"]/div[2]/div/div[1]/div[1]').screenshot_as_png

         qrcode_img = Image.open(BytesIO(qrcode_img_data))

         qrcode_img.save('qrcode.png')

         qrcode_img.show()

         print(" 請掃碼登入! ")

         time.sleep(2)

         # 每隔 1.5 秒判斷一次是否登入成功

         t=0

         while t < 40:

             try:

                 info = browser.find_element(By.XPATH, '//*[@id="J_Col_Main"]/div/div[1]/div/div[1]/div[1]/div/div[1]/a/em').text

                 print(' 您的帳戶 :' + info)

                 for proc in psutil.process_iter():  # 遍歷當前 process

                     if proc.name() == "Microsoft.Photos.exe":

                         proc.kill()  # 關閉該 process

                 break

             except:

                 time.sleep(1.5)

                 t+=1

         # 獲取 Cookie 並保持在 session

         cookies = browser.get_cookies()

         time.sleep(round(random.uniform(1,2),2))

         browser.quit()

         selenium_cookies = cookies

         tmp_cookies = RequestsCookieJar()

         for item in selenium_cookies:

             tmp_cookies.set(item["name"], item["value"])

         self.session.cookies.update(tmp_cookies)

     # 登入

     def login(self):

         print(" 登入中 ...")

         try:

             req=self.session.get(').text

             if self.key_word1 in req:

                 print(" 自動登入成功! ")

             else:

                 print(" 自動登入失敗! \n 請再次掃碼登入! ")

                 self.get_cookies()

                 self.session.get(').text

                 if self.key_word1 in req:

                     print(" 自動登入成功! ")

                 else:

                     print(" 自動登入失敗! \n 請手動完成該任務 ")

                     sys.exit(0)

         except:

             print(' 程式出錯! ')

             sys.exit(0)

     # 提交訂單

     def submitOrder(self, url, skuId, setTime, quantity):

         self.url = url

         quantity = '_' + quantity + '_'

         # 獲取 cookies 並登入

         self.cookies=self.get_cookies()

         self.login()

         time.sleep(round(random.uniform(1,2),2))

         # 進入商品詳情頁

         self.req = self.session.get(url=self.url).text

         time.sleep(round(random.uniform(1,2),2))

         # 提取 key datas

         self.patterGoods()

         time.sleep(round(random.uniform(1,2),2))

         # 確認訂單

         data = {

             "buy_param": self.auction[0] + quantity + skuId

         }

         url = ' + self.auction[0] + '&x-uid=' + self.userId[0]

         k = 0

         while True:

             print("\r 購買倒數計時: %.3f"%(setTime-time.time()),end="",flush=True)

             if (time.time() >= setTime):

                 print('\n')

                 print(datetime.datetime.now())

                 while True:

                     self.req = self.session.post(url=url, data=data).text

                     # 獲取資料

                     key = self.patterData()

                     k+=1

                     if(k==50):

                         print("\n 確認訂單失敗!下次加油哦 ")

                         print(datetime.datetime.now())

                         sys.exit(0)

                     if(key):

                         print("\n 確認訂單成功! ")

                         print(datetime.datetime.now())

                         break

                 break

         # 提交訂單

         data = {

             "endpoint": self.endpoint,

             "linkage": self.linkage,

             "data": self.data,

             "action": self.action,

             "_tb_token_": self.tbToken,

             "event_submit_do_confirm": self.event,

             "praper_alipay_cashier_domain": self.unitSuffix,

             "input_charset": self.charset,

             "hierarchy": self.hierarchy

         }

         url = ' + self.auction[0] + '&x-uid=' + self.userId[0] + '&submitref=' + self.submitUrl

         # 多執行緒,提高搶購效率

         thread_list=[]

         for i in range(1,80):

             t = threading.Thread(target=self.post, args=(url, data))

             thread_list.append(t)

         l = len(thread_list)

         # 啟動執行緒

         for i in range(0,l-1):

             thread_list[i].start()

         # 關閉執行緒

         for t in range(0,l-1):

             thread_list[i].join()

         while self.queue.empty() == False:

             req = self.queue.get()

             if self.key_word2 in req:

                 print(' 提交訂單成功!請快儘快付款! ')

                 self.j = 1

                 break

         if self.j == 0:

             print(' 提交訂單失敗!請下次重試! ')

         print('Buy End!')

         sys.exit(0)

     # 提取資訊:商品詳情

     def patterGoods(self):

         # 頁面 id

         self.auction=re.findall(r'(?<=auction=).*?(?=&)', self.req)

         # 使用者 id

         self.userId=re.findall(r'(?<=&userid=).*?(?=&)', self.req)

         # 購買端 token

         tbTokens=re.findall(r'(?<=yunid=&).*?(?=&)', self.req)

         self.tbToken = tbTokens[0]

     # 提取資訊:生成訂單資料

     def patterData(self):

         # 正則匹配

         data=re.findall(r'(?<="secretValue":).*?(?=,"unitSuffix")', self.req)

         if not data:

             return False    

         self.submitUrl = ''.join(data)

         self.submitUrl=re.sub(r'"', '', self.submitUrl)

         self.submitUrl=re.sub(r',', '&', self.submitUrl)

         self.submitUrl=re.sub(r':', '=', self.submitUrl)

         data = re.findall(r'(?<="endpoint":).*?(?=,"data")', self.req)

         self.endpoint = ''.join(data)

         self.endpoint = quote(self.endpoint)

         data = re.findall(r'(?<="action":").*?(?=","event_submit_do_confirm")', self.req)

         self.action = ''.join(data)

         data = re.findall(r'(?<="event_submit_do_confirm":").*?(?=","input_charset")', self.req)

         self.event = ''.join(data)

         data = re.findall(r'(?<="input_charset":").*?(?=","pcSubmitUrl")', self.req)

         self.charset =外匯跟單gendan5.com ''.join(data)

         data = re.findall(r'(?<="unitSuffix":").*?(?="}},)', self.req)

         unitSuffix = ''.join(data)

         self.unitSuffix = "cashier" + unitSuffix

         data=re.findall(r'(?<="data":).*?(?=,"linkage")', self.req)

         self.data = ''.join(data)

         self.data = quote(self.data)     # url 編碼

         data=re.findall(r'(?<="linkage":).*?(?=,"hierarchy")', self.req)

         self.linkage = ''.join(data)

         self.linkage = quote(self.linkage)

         data=re.findall(r'(?<="hierarchy":).*?(?=,"container")', self.req)

         self.hierarchy = ''.join(data)

         self.hierarchy = quote(self.hierarchy)

         return True

     def post(self, url, data):

         req = self.session.post(url=url, data=data).text

         self.queue.put(req)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2931957/,如需轉載,請註明出處,否則將追究法律責任。