Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menggunakan Python untuk menulis skrip untuk membuat pesanan secara automatik di JD.com?

Bagaimana untuk menggunakan Python untuk menulis skrip untuk membuat pesanan secara automatik di JD.com?

WBOY
WBOYke hadapan
2023-05-06 19:52:174419semak imbas

1 Latar Belakang masalah

Selepas banyak pembelian tergesa-gesa gagal, saya mendapati bahawa peniaga akan mengeluarkan sejumlah kecil bekalan dari semasa ke semasa, dan saya menganggarkan secara visual bilangan unit yang ada pada setiap masa. Jika kami menulis skrip untuk memantau inventori produk 24 jam sehari, dan setelah sumber barang ditanya, kami akan cuba membuat pesanan secara automatik, yang boleh meningkatkan kebarangkalian kami untuk berjaya.

2 Idea Reka Bentuk

Pembelian produk tergesa-gesa Jingdong terbahagi kepada dua jenis:

Pembelian tergesa-gesa temu janji: terbuka untuk pembelian di tempat, sama seperti proses pesanan untuk produk biasa; produk jualan kilat : Antara muka snap-up yang berasingan dan proses pesanan.

Semestinya kali ini ia disasarkan kepada pembelian tergesa-gesa tempahan atau pesanan kehabisan stok iaitu keseluruhan proses tempahan adalah sama seperti semasa membeli barangan biasa:

登录账号 → 进入购物车 → 选择抢购商品 → 点击去结算 → 点击提交订单 → 选择付款方式并付款.

3 Pelaksanaan Khusus

Memandangkan pengarang tidak mempunyai pelanggan yang boleh menangkap paket, saya memutuskan untuk menggunakan antara muka WEB JD.com untuk melaksanakan program skrip kami.

Jadi selepas menganalisis proses pesanan di laman web JD.com, program skrip kami dibahagikan kepada empat modul: Modul log masuk akaun, Modul pemantauan inventori, Modul pengurusan troli beli-belah, modul pengurusan pesanan.

3.1 Log masuk akaun

Memandangkan terdapat sekatan kod pengesahan apabila menggunakan kata laluan akaun, imbas kod QR untuk log masuk untuk memintasnya.

Bagi pelajar yang tidak biasa atau berminat untuk mengimbas log masuk kod, anda boleh menyemak catatan blog Zhou Zhou sebelum ini mengenai prinsip dan pelaksanaan log masuk kod imbasan.

Kali ini saya hanya perlu melakukan analisis tangkapan paket pada halaman log masuk JD dan mencari beberapa antara muka yang berguna:

Dapatkan kod QR log masuk
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
Dapatkan Tiket
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']
Sahkan Tiket
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']

Selepas mengesahkan bahawa Tiket itu sah, gunakan perpustakaan pickle untuk menyimpan kuki dalam sesi program secara tempatan untuk masa seterusnya digunakan.

3.2 Pemantauan Inventori

Pemantauan inventori agak mudah Analisis halaman butiran produk dan dapatkan ID kedai dan atribut klasifikasi produk:

Dapatkan maklumat butiran produk<.>
def getItemDetail(self, skuId):
    url = &#39;https://item.jd.com/{}.html&#39;.format(skuId)
    page = requests.get(url=url, headers=self.headers)

    html = etree.HTML(page.text)
    vender = html.xpath(
        &#39;//div[@class="follow J-follow-shop"]/@data-vid&#39;)[0]
    cat = html.xpath(&#39;//a[@clstag="shangpin|keycount|product|mbNav-3"]/@href&#39;)[
        0].replace(&#39;//list.jd.com/list.html?cat=&#39;, &#39;&#39;)

    if not vender or not cat:
        raise Exception(&#39;获取商品信息失败,请检查SKU是否正确&#39;)

    detail = dict(catId=cat, venderId=vender)
    return detail
Semak inventori
def getItemStock(self, skuId, num, areaId):

    item = self.itemDetails.get(skuId)

    if not item:
        return False

    url = &#39;https://c0.3.cn/stock&#39;
    payload = {
        &#39;skuId&#39;: skuId,
        &#39;buyNum&#39;: num,
        &#39;area&#39;: areaId,
        &#39;ch&#39;: 1,
        &#39;_&#39;: str(int(time.time() * 1000)),
        &#39;callback&#39;: &#39;jQuery{}&#39;.format(random.randint(1000000, 9999999)),
        # get error stock state without this param
        &#39;extraParam&#39;: &#39;{"originid":"1"}&#39;,
        # get 403 Forbidden without this param (obtained from the detail page)
        &#39;cat&#39;: item.get(&#39;catId&#39;),
        # return seller information with this param (can&#39;t be ignored)
        &#39;venderId&#39;: item.get(&#39;venderId&#39;)
    }
    headers = {
        &#39;User-Agent&#39;: self.userAgent,
        &#39;Referer&#39;: &#39;https://item.jd.com/{}.html&#39;.format(skuId),
    }

    respText = &#39;&#39;
    try:
        respText = requests.get(
            url=url, params=payload, headers=headers, timeout=self.timeout).text
        respJson = self.parseJson(respText)
        stockInfo = respJson.get(&#39;stock&#39;)
        skuState = stockInfo.get(&#39;skuState&#39;)  # 商品是否上架
        # 商品库存状态:33 -- 现货  0,34 -- 无货  36 -- 采购中  40 -- 可配货
        stockState = stockInfo.get(&#39;StockState&#39;)
        return skuState == 1 and stockState in (33, 40)
3.3 Operasi troli beli-belah

Kami tidak boleh menambah barang kehabisan stok ke troli beli-belah melalui halaman operasi, tetapi kita boleh melakukannya di sini Cuba gunakan produk dalam stok lain, terutamanya semak tambah, padam, ubah suai dan semak antara muka troli beli-belah:

Batalkan semua produk yang dipilih
def uncheckCartAll(self):
    """ 取消所有选中商品
    return 购物车信息
    """
    url = &#39;https://api.m.jd.com/api&#39;

    headers = {
        &#39;User-Agent&#39;: self.userAgent,
        &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
        &#39;origin&#39;: &#39;https://cart.jd.com&#39;,
        &#39;referer&#39;: &#39;https://cart.jd.com&#39;
    }

    data = {
        &#39;functionId&#39;: &#39;pcCart_jc_cartUnCheckAll&#39;,
        &#39;appid&#39;: &#39;JDC_mall_cart&#39;,
        &#39;body&#39;: &#39;{"serInfo":{"area":"","user-key":""}}&#39;,
        &#39;loginType&#39;: 3
    }

    resp = self.sess.post(url=url, headers=headers, data=data)

    # return self.respStatus(resp) and resp.json()[&#39;success&#39;]
    return resp
Tambah pada troli beli-belah
def addCartSku(self, skuId, skuNum):
    """ 加入购入车
    skuId 商品sku
    skuNum 购买数量
    retrun 是否成功
    """
    url = &#39;https://api.m.jd.com/api&#39;
    headers = {
        &#39;User-Agent&#39;: self.userAgent,
        &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
        &#39;origin&#39;: &#39;https://cart.jd.com&#39;,
        &#39;referer&#39;: &#39;https://cart.jd.com&#39;
    }
    data = {
        &#39;functionId&#39;: &#39;pcCart_jc_cartAdd&#39;,
        &#39;appid&#39;: &#39;JDC_mall_cart&#39;,
        &#39;body&#39;: &#39;{\"operations\":[{\"carttype\":1,\"TheSkus\":[{\"Id\":\"&#39; + skuId + &#39;\",\"num\":&#39; + str(skuNum) + &#39;}]}]}&#39;,
        &#39;loginType&#39;: 3
    }
    resp = self.sess.post(url=url, headers=headers, data=data)
    return self.respStatus(resp) and resp.json()[&#39;success&#39;]
Ubah suai bilangan barang dalam troli beli-belah
def changeCartSkuCount(self, skuId, skuUid, skuNum, areaId):
    """ 修改购物车商品数量
    skuId 商品sku
    skuUid 商品用户关系
    skuNum 购买数量
    retrun 是否成功
    """
    url = &#39;https://api.m.jd.com/api&#39;
    headers = {
        &#39;User-Agent&#39;: self.userAgent,
        &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
        &#39;origin&#39;: &#39;https://cart.jd.com&#39;,
        &#39;referer&#39;: &#39;https://cart.jd.com&#39;
    }
    body = &#39;{\"operations\":[{\"TheSkus\":[{\"Id\":\"&#39;+skuId+&#39;\",\"num\":&#39;+str(
        skuNum)+&#39;,\"skuUuid\":\"&#39;+skuUid+&#39;\",\"useUuid\":false}]}],\"serInfo\":{\"area\":\"&#39;+areaId+&#39;\"}}&#39;
    data = {
        &#39;functionId&#39;: &#39;pcCart_jc_changeSkuNum&#39;,
        &#39;appid&#39;: &#39;JDC_mall_cart&#39;,
        &#39;body&#39;: body,
        &#39;loginType&#39;: 3
    }
    resp = self.sess.post(url=url, headers=headers, data=data)
    return self.respStatus(resp) and resp.json()[&#39;success&#39;]
Di atas adalah minimum antara muka yang perlu kami gunakan untuk pembelian Untuk tidak memusnahkan data sedia ada dalam troli beli-belah akaun, gunakan Sediakan troli beli-belah dalam langkah berikut:

Nyahtanda semua item (kembali ke maklumat troli beli-belah); ubah suai kuantiti barang jika ia sudah ada di dalam troli beli-belah; 3.4 Operasi pesanan

Selepas kami menyediakan troli beli-belah (pilih item untuk dibeli dan laraskan kuantiti pembelian), kami boleh meneruskan operasi berkaitan pesanan seterusnya:

Dapatkan borang penyelesaian
def getCheckoutPage(self):
    """获取订单结算页面信息
    :return: 结算信息 dict
    """
    url = &#39;http://trade.jd.com/shopping/order/getOrderInfo.action&#39;
    # url = &#39;https://cart.jd.com/gotoOrder.action&#39;
    payload = {
        &#39;rid&#39;: str(int(time.time() * 1000)),
    }
    headers = {
        &#39;User-Agent&#39;: self.userAgent,
        &#39;Referer&#39;: &#39;https://cart.jd.com/cart&#39;,
    }
Serahkan pesanan
def submitOrder(self):
    """提交订单
    :return: True/False 订单提交结果
    """
    url = &#39;https://trade.jd.com/shopping/order/submitOrder.action&#39;
    # js function of submit order is included in https://trade.jd.com/shopping/misc/js/order.js?r=2018070403091

    data = {
        &#39;overseaPurchaseCookies&#39;: &#39;&#39;,
        &#39;vendorRemarks&#39;: &#39;[]&#39;,
        &#39;submitOrderParam.sopNotPutInvoice&#39;: &#39;false&#39;,
        &#39;submitOrderParam.trackID&#39;: &#39;TestTrackId&#39;,
        &#39;submitOrderParam.ignorePriceChange&#39;: &#39;0&#39;,
        &#39;submitOrderParam.btSupport&#39;: &#39;0&#39;,
        &#39;riskControl&#39;: self.risk_control,
        &#39;submitOrderParam.isBestCoupon&#39;: 1,
        &#39;submitOrderParam.jxj&#39;: 1,
        &#39;submitOrderParam.trackId&#39;: self.track_id,
        &#39;submitOrderParam.eid&#39;: self.eid,
        &#39;submitOrderParam.fp&#39;: self.fp,
        &#39;submitOrderParam.needCheck&#39;: 1,
    }

Atas ialah kandungan terperinci Bagaimana untuk menggunakan Python untuk menulis skrip untuk membuat pesanan secara automatik di JD.com?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam