小程序付航脱口秀抢票脚本

一、前言

付航越火,票越难抢。技术抢票,快乐看猴~

二、工具

(1)PC端微信(windows系统)、手机微信

(2)fiddler抓包工具

(3)python

三、流程

(1)手机端微信搜索小程序付航脱口秀,登录后填写抢票信息(手机端操作方便,抓包备用)。注意:本文脚本只适用于抢普通区,单张票(单身狗看猴专属)

(2)打开fiddler抓包工具,设置Filters,只筛选付航脱口秀相关请求。

(3)PC端微信搜索付航脱口秀,点击到准备抢票页面,至此所要用到的连接都已加载完毕。

(4)分析请求参数,最后一步提交抢票请求要用到的参数。

(4.1)请求一:获取定位信息请求(见下图),返回cityId、bsCityId两个参数,这两个参数在最后提交订单的请求中会用到,定位信息一般不会改,可以写成固定值。

(4.2)请求二:获取抢票预填信息的请求(见下图),关键参数都是从这个请求返回的

        headers中重点参数是access-token,这个参数是登录小程序时后台返回的,每次抢票前都要手动更新。还有一个参数front-trace-id,是由时间戳和随机数组成(如下)。headers中其他参数都是固定值。

front_trace_id = Date.now().toString(36) + Math.random().toString(36).substring(2)

(4.3)请求三:提交抢票。这个请求只有在每周二下午6点正式抢票时才能抓到。

        headers中重点参数(同请求二)。

        请求体中的参数很多,但大多是固定值,需要更新的有以下几个:

  1.             ver = "4.19.7"                                   #可从抓包请求头复制
  2.             bsCityId = "BL1111"                         #省份id,上文请求一中获取
  3.             locationCityId = "3205"                    #城市id,上文请求一中获取
  4.             preFiledId = ""                                 #预填信息id,上文请求二中获取
  5.             audienceId = ""                               #观众id,上文请求二中获取
  6.             skuId = ""                                        #座位类型id,上文请求二中获取
  7.             showId = ""                                     #演出id,上文请求二中获取
  8.             sessionId = ""                                 #具体时间端的演出id,上文请求二中获取

四、代码(以下请求中的access_token要替换成自己的)

(1)上文请求二的代码:获取抢票预填信息

#获取front_trace_id
def get_front_trace_id():
    with open('get_front_trace_id.js', 'r', encoding='utf-8') as f:
        src = f.read()
    js_code = execjs.compile(src)
    front_trace_id = js_code.call('trace_id')
    return front_trace_id


#获取预填信息
def get_prefilledlist(access_token):
    url = 'https://65373d6e95c3170001074c57.caiyicloud.com/cyy_gatewayapi/show/buyer/v3/pre_filed_info/670e7a8f3d2d3000018bbf64'
    headers = {
        "Host": "65373d6e95c3170001074c57.caiyicloud.com",
        "Connection": "keep-alive",
        "terminal-src": "WEIXIN_MINI",
        "content-type": "application/json",
        "src": "weixin_mini",
        "ver": ver,
        "access-token": access_token,
        "merchant-id": "65373d6e95c3170001074c57",
        "front-trace-id": get_front_trace_id(),
        "Accept-Encoding": "gzip,compress,br,deflate",
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.44(0x18002c2f) NetType/4G Language/zh_CN",
        "Referer": "https://servicewechat.com/wxe3489c9feaf8f361/39/page-frame.html"
    }
    params = {
        "needDetails": "true",
        "source": "FROM_SHOW_DETAIL_PRE_FILED",
        "src": "weixin_mini",
        "merchantId": "65373d6e95c3170001074c57",
        "ver": "4.19.7",
        "appId": "wxe3489c9feaf8f361"
    }
    res = requests.get(url=url, headers=headers, json=params)
    prefilledlist = res.json()['data']
    preFiledId = prefilledlist['preFiledId']  # preFiledId
    audienceId = prefilledlist['userAudienceIds'][0]  # userAudienceIds[0]
    skuId = prefilledlist['bizSeatPlanId']  # bizSeatPlanId
    showId = prefilledlist['bizShowId']  # bizShowId
    sessionId = prefilledlist['bizShowSessionId']  # bizShowSessionId
    return preFiledId, audienceId, skuId, showId, sessionId 
(2)get_front_trace_id.js代码
function trace_id() {
    return Date.now().toString(36) + Math.random().toString(36).substring(2)
}

(3)上文请求三的代码:提交抢票请求

#提交抢票请求
def get_ticket(ver,bsCityId,locationCityId,preFiledId,audienceId,skuId,showId,sessionId,access_token):
    url = 'https://65373d6e95c3170001074c57.caiyicloud.com/cyy_gatewayapi/trade/buyer/order/v5/create_order'
    headers = {
        "Host": "65373d6e95c3170001074c57.caiyicloud.com",
        "Connection": "keep-alive",
        "terminal-src": "WEIXIN_MINI",
        "content-type": "application/json",
        "src": "weixin_mini",
        "ver": ver,
        "access-token": access_token,
        "merchant-id": "65373d6e95c3170001074c57",
        "front-trace-id": get_front_trace_id(),
        "Accept-Encoding": "gzip,compress,br,deflate",
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.44(0x18002c2f) NetType/4G Language/zh_CN",
        "Referer": "https://servicewechat.com/wxe3489c9feaf8f361/39/page-frame.html"
    }
    params = {
        "locationParam" : {
            "bsCityId" : bsCityId,
            "locationCityId" : locationCityId
        },
        "preFiledId" : preFiledId,
        "priceItemParam" : [
            {
                "applyTickets" : [

                ],
                "priceItemType" : "TICKET_FEE",
                "priceItemSpecies" : "SEAT_PLAN",
                "priceItemVal" : "220.00",
                "priceDisplay" : "¥220",
                "priceItemName" : "票款总额",
                "direction" : "INCREASE"
            }
        ],
        "merchantId" : "65373d6e95c3170001074c57",
        "src" : "weixin_mini",
        "appId" : "wxe3489c9feaf8f361",
        "priorityId" : "",
        "orderSource" : "COMMON",
        "addressParam" : {

        },
        "many2OneAudience" : {

        },
        "ver" : ver,
        "items" : [
            {
                "sku" : {
                    "ticketItems" : [
                        {
                            "id" : "1729591200100100000008",
                            "audienceId" : audienceId
                        }
                    ],
                    "ticketPrice" : "220.00",
                    "skuId" : skuId,
                    "qty" : 1,
                    "skuType" : "SINGLE"
                },
                "spu" : {
                    "addPromoVersionHash" : "EMPTY_PROMOTION_HASH",
                    "promotionVersionHash" : "EMPTY_PROMOTION_HASH",
                    "showId" : showId,
                    "sessionId" : sessionId
                },
                "deliverMethod" : "E_TICKET"
            }
        ],
        "paymentParam" : {
            "totalAmount" : "220.00",
            "payAmount" : "220.00"
        },
        "addPurchasePromotionId" : ""
    }
    res = requests.post(url=url, headers=headers, json=params)
    return res

(4)提交订单请求成功后,需要手动付款。

关注公众号【抢票源码笔记】,可获取完整教程。

声明:本文仅供技术学习交流。