ホームページ >バックエンド開発 >Python チュートリアル >Python を使用して JD.com で自動的に注文するスクリプトを作成するにはどうすればよいですか?

Python を使用して JD.com で自動的に注文するスクリプトを作成するにはどうすればよいですか?

WBOY
WBOY転載
2023-05-06 19:52:174515ブラウズ

1 問題の背景

数え切れないほどの駆け込み購入の試みが失敗した後、販売業者が時々少量の供給を放出することがわかり、それぞれの販売単位に何個あるのかを視覚的に見積もりました。時間。製品在庫を 24 時間監視するスクリプトを作成し、商品の供給元が照会されると、自動的に発注しようとするため、成功の可能性が大幅に高まります。

2 デザインアイデア

京東の商品の急ぎ購入は主に 2 つのタイプに分けられます:

予約の急ぎ購入: 注文プロセスと同じポイントで購入できます。通常商品、フラッシュセール商品: 個別のスナップアップインターフェイスと注文プロセス。

もちろん、今回は予約の殺到や在庫切れの注文をターゲットとしています。つまり、全体的な注文プロセスは通常の商品を購入する場合と同じです。

アカウントにログイン→ショッピングカートに入力→スナップする製品を選択→クリックしてチェックアウト→クリックして注文を送信→支払い方法を選択し、支払いを行います

3 具体的な実装

著者はパケットをキャプチャできるクライアントを持っていないため、JD.com の WEB インターフェイスを使用してスクリプト プログラムを実装することにしました。

したがって、京東の Web ページでの注文プロセスを分析した後、スクリプト プログラムは 4 つのモジュールに分割されました: アカウント ログイン モジュール在庫監視モジュールショッピング カート管理モジュール注文管理モジュール。

3.1 アカウントのログイン

アカウントのパスワードを使用する場合は確認コードの制限があるため、これを回避するには QR コードをスキャンしてログインします。

スキャン コード ログインに詳しくない、またはスキャン コード ログインに興味がある学生の場合は、スキャン コード ログインの原理と実装に関する Zhou Zhou の以前のブログ投稿を確認してください。

今回は、JD ログイン ページでパケット キャプチャ分析を実行し、いくつかの便利なインターフェイスを見つけるだけです:

ログイン QR コードを取得します
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
Get 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']
Verify 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']

チケットが有効であることを確認した後、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 を使用して JD.com で自動的に注文するスクリプトを作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。