1. <s id="4jtld"></s>
    1. <span id="4jtld"><meter id="4jtld"></meter></span>

        <span id="4jtld"></span>
      1. <s id="4jtld"><noscript id="4jtld"><i id="4jtld"></i></noscript></s>
        溫馨提示×

        怎么用Python寫一個京東自動下單搶購腳本

        發布時間:2023-03-23 17:24:02 來源:億速云 閱讀:87 作者:iii 欄目:開發技術

        本文小編為大家詳細介紹“怎么用Python寫一個京東自動下單搶購腳本”,內容詳細,步驟清晰,細節處理妥當,希望這篇“怎么用Python寫一個京東自動下單搶購腳本”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

        1 問題背景

        經過無數次搶購失敗后,發現商家會不定時的放出少量貨源,目測每次會有幾臺。如果我們編寫一個腳本程序24小時不間斷監聽商品庫存,一旦查詢到貨源便開始嘗試自動下單,這樣就可以極大提高我們的成功概率。

        2 設計思路

        京東對于商品的搶購主要分為兩種:

        預約搶購:到點開放購買,和普通商品下單流程一致;秒殺商品:單獨的搶購接口和下單流程。

        當然本次針對的預約搶購類或無貨訂購類,即整體下單流程和購買普通商品時一樣:

        登錄賬號 &rarr; 進入購物車 &rarr; 選擇搶購商品 &rarr; 點擊去結算 &rarr; 點擊提交訂單 &rarr; 選擇付款方式并付款。

        3 具體實現

        由于筆者本人沒有一個可以抓包的客戶端,決定采用京東 WEB 端接口實現我們的腳本程序。

        于是經過對京東網頁下單流程的分析,將我們的腳本程序分為四個模塊:賬號登錄模塊、庫存監聽模塊、購物車管理模塊、訂單管理模塊。

        3.1 賬號登錄

        由于使用賬號密碼時有驗證碼限制,此處采用掃碼登錄方式繞過。

        如對掃碼登錄不熟悉或感興趣的同學可以查看周周之前的博文 掃碼登錄原理和實現。

        本次只要針對京東登錄頁進行抓包分析,找到幾個有用接口:

        獲取登錄二維碼
        def getQRcode(self):
            url = 'https://qr.m.jd.com/show'
            payload = {
                'appid': 133,
                'size': 147,
                't': str(int(time.time() * 1000)),
            }
            headers = {
                'User-Agent': self.userAgent,
                'Referer': 'https://passport.jd.com/new/login.aspx',
            }
            resp = self.sess.get(url=url, headers=headers, params=payload)
        
            if not self.respStatus(resp):
                return None
        
            return resp.content
        獲取Ticket
        def getQRcodeTicket(self):
            url = 'https://qr.m.jd.com/check'
            payload = {
                'appid': '133',
                'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
                'token': self.sess.cookies.get('wlfstk_smdl'),
                '_': str(int(time.time() * 1000)),
            }
            headers = {
                'User-Agent': self.userAgent,
                'Referer': 'https://passport.jd.com/new/login.aspx',
            }
            resp = self.sess.get(url=url, headers=headers, params=payload)
        
            if not self.respStatus(resp):
                return False
        
            respJson = self.parseJson(resp.text)
            if respJson['code'] != 200:
                return None
            else:
                return respJson['ticket']
        驗證 Ticket
        def getQRcodeTicket(self):
            url = 'https://qr.m.jd.com/check'
            payload = {
                'appid': '133',
                'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
                'token': self.sess.cookies.get('wlfstk_smdl'),
                '_': str(int(time.time() * 1000)),
            }
            headers = {
                'User-Agent': self.userAgent,
                'Referer': 'https://passport.jd.com/new/login.aspx',
            }
            resp = self.sess.get(url=url, headers=headers, params=payload)
        
            if not self.respStatus(resp):
                return False
        
            respJson = self.parseJson(resp.text)
            if respJson['code'] != 200:
                return None
            else:
                return respJson['ticket']

        此時驗證 Ticket 有效后使用 pickle 庫將程序會話中的 cookie 保存到本地以便下次使用。

        3.2 庫存監聽

        庫存監聽較為簡單,分析商品詳情頁,獲取店鋪ID以及商品分類屬性:

        獲取商品詳情信息
        def getItemDetail(self, skuId):
            url = 'https://item.jd.com/{}.html'.format(skuId)
            page = requests.get(url=url, headers=self.headers)
        
            html = etree.HTML(page.text)
            vender = html.xpath(
                '//div[@class="follow J-follow-shop"]/@data-vid')[0]
            cat = html.xpath('//a[@clstag="shangpin|keycount|product|mbNav-3"]/@href')[
                0].replace('//list.jd.com/list.html?cat=', '')
        
            if not vender or not cat:
                raise Exception('獲取商品信息失敗,請檢查SKU是否正確')
        
            detail = dict(catId=cat, venderId=vender)
            return detail
        查詢庫存
        def getItemStock(self, skuId, num, areaId):
        
            item = self.itemDetails.get(skuId)
        
            if not item:
                return False
        
            url = 'https://c0.3.cn/stock'
            payload = {
                'skuId': skuId,
                'buyNum': num,
                'area': areaId,
                'ch': 1,
                '_': str(int(time.time() * 1000)),
                'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
                # get error stock state without this param
                'extraParam': '{"originid":"1"}',
                # get 403 Forbidden without this param (obtained from the detail page)
                'cat': item.get('catId'),
                # return seller information with this param (can't be ignored)
                'venderId': item.get('venderId')
            }
            headers = {
                'User-Agent': self.userAgent,
                'Referer': 'https://item.jd.com/{}.html'.format(skuId),
            }
        
            respText = ''
            try:
                respText = requests.get(
                    url=url, params=payload, headers=headers, timeout=self.timeout).text
                respJson = self.parseJson(respText)
                stockInfo = respJson.get('stock')
                skuState = stockInfo.get('skuState')  # 商品是否上架
                # 商品庫存狀態:33 -- 現貨  0,34 -- 無貨  36 -- 采購中  40 -- 可配貨
                stockState = stockInfo.get('StockState')
                return skuState == 1 and stockState in (33, 40)

        3.3 購物車操作

        無貨商品加入到購物車我們是無法通過頁面操作的,我們這邊可以使用其他有貨商品進行嘗試,主要查看購物車的增刪改查接口:

        取消所有選中商品
        def uncheckCartAll(self):
            """ 取消所有選中商品
            return 購物車信息
            """
            url = 'https://api.m.jd.com/api'
        
            headers = {
                'User-Agent': self.userAgent,
                'Content-Type': 'application/x-www-form-urlencoded',
                'origin': 'https://cart.jd.com',
                'referer': 'https://cart.jd.com'
            }
        
            data = {
                'functionId': 'pcCart_jc_cartUnCheckAll',
                'appid': 'JDC_mall_cart',
                'body': '{"serInfo":{"area":"","user-key":""}}',
                'loginType': 3
            }
        
            resp = self.sess.post(url=url, headers=headers, data=data)
        
            # return self.respStatus(resp) and resp.json()['success']
            return resp
        加入購入車
        def addCartSku(self, skuId, skuNum):
            """ 加入購入車
            skuId 商品sku
            skuNum 購買數量
            retrun 是否成功
            """
            url = 'https://api.m.jd.com/api'
            headers = {
                'User-Agent': self.userAgent,
                'Content-Type': 'application/x-www-form-urlencoded',
                'origin': 'https://cart.jd.com',
                'referer': 'https://cart.jd.com'
            }
            data = {
                'functionId': 'pcCart_jc_cartAdd',
                'appid': 'JDC_mall_cart',
                'body': '{\"operations\":[{\"carttype\":1,\"TheSkus\":[{\"Id\":\"' + skuId + '\",\"num\":' + str(skuNum) + '}]}]}',
                'loginType': 3
            }
            resp = self.sess.post(url=url, headers=headers, data=data)
            return self.respStatus(resp) and resp.json()['success']
        修改購物車商品數量
        def changeCartSkuCount(self, skuId, skuUid, skuNum, areaId):
            """ 修改購物車商品數量
            skuId 商品sku
            skuUid 商品用戶關系
            skuNum 購買數量
            retrun 是否成功
            """
            url = 'https://api.m.jd.com/api'
            headers = {
                'User-Agent': self.userAgent,
                'Content-Type': 'application/x-www-form-urlencoded',
                'origin': 'https://cart.jd.com',
                'referer': 'https://cart.jd.com'
            }
            body = '{\"operations\":[{\"TheSkus\":[{\"Id\":\"'+skuId+'\",\"num\":'+str(
                skuNum)+',\"skuUuid\":\"'+skuUid+'\",\"useUuid\":false}]}],\"serInfo\":{\"area\":\"'+areaId+'\"}}'
            data = {
                'functionId': 'pcCart_jc_changeSkuNum',
                'appid': 'JDC_mall_cart',
                'body': body,
                'loginType': 3
            }
            resp = self.sess.post(url=url, headers=headers, data=data)
            return self.respStatus(resp) and resp.json()['success']

        以上是我們一次購買需要用到的最少接口,為了不破壞賬戶購物車中已有數據,采用一下步驟準備好購物車:

        取消全部勾選(返回購物車信息);已在購物車則修改商品數量;不在購物車則加入購物車。 3.4 訂單操作

        當我們準備好購物車之后(選中購買商品以及調整購買數量),就可以進行下一步訂單相關操作:

        獲取結算單
        def getCheckoutPage(self):
            """獲取訂單結算頁面信息
            :return: 結算信息 dict
            """
            url = 'http://trade.jd.com/shopping/order/getOrderInfo.action'
            # url = 'https://cart.jd.com/gotoOrder.action'
            payload = {
                'rid': str(int(time.time() * 1000)),
            }
            headers = {
                'User-Agent': self.userAgent,
                'Referer': 'https://cart.jd.com/cart',
            }
        提交訂單
        def submitOrder(self):
            """提交訂單
            :return: True/False 訂單提交結果
            """
            url = 'https://trade.jd.com/shopping/order/submitOrder.action'
            # js function of submit order is included in https://trade.jd.com/shopping/misc/js/order.js?r=2018070403091
        
            data = {
                'overseaPurchaseCookies': '',
                'vendorRemarks': '[]',
                'submitOrderParam.sopNotPutInvoice': 'false',
                'submitOrderParam.trackID': 'TestTrackId',
                'submitOrderParam.ignorePriceChange': '0',
                'submitOrderParam.btSupport': '0',
                'riskControl': self.risk_control,
                'submitOrderParam.isBestCoupon': 1,
                'submitOrderParam.jxj': 1,
                'submitOrderParam.trackId': self.track_id,
                'submitOrderParam.eid': self.eid,
                'submitOrderParam.fp': self.fp,
                'submitOrderParam.needCheck': 1,
            }

        讀到這里,這篇“怎么用Python寫一個京東自動下單搶購腳本”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

        免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

        主題地圖

        欧美午夜理伦三级在线观看,欧美午夜乱伦片,欧美午夜乱色视频在线观看,欧美午夜免费一区二区,欧美午夜片欧美片在线观看