当前位置:   article > 正文

大麦安卓抢票脚本_抢不到票?你离idol只差一个脚本。

手机抢票脚本

6c859c32ead432260826808bc5281be2.png

94f0a4f4274028fc8af2a849db646b4f.png

热门演唱会门票不到一分钟就可能卖光,不知道要多快的手速才能一鼓作气点点点及时下单。走一下神可能就不得不选个差一点的区域,甚至只能高价求票了。

好朋友遇到了这样的烦恼,我一想这种比较机械的刷新其实很适合用脚本完成呀,所以就花了一个下午有了这个脚本。

目前还是比较有局限性的:

  • 稳定性没有100%保证,如果是很重要的票可能一边开着电脑用脚本,一边自己用手机刷新更保险一些,做好两手准备

  • 需要手动在脚本中修改人数

  • 只支持大麦演唱会,不支持歌剧话剧,比赛等

  • 不支持选座

  • 需要事先登录好,填好相关的地址,人员信息

  • UI太粗糙啦

如果你想直接使用现成的脚本  → 从安装Tampermonkey到成功抢到演唱会门票

如果你对怎么写脚本感兴趣  → 怎么写一个抢票脚本

从安装Tampermonkey到成功抢到演唱会门票

建议用Chrome浏览器使用这个脚本因为我就是在Chrome写的,其他浏览器没怎么测试,大家试用后有什么问题可以给我留言提意见反馈。

Tampermonkey可以很方便的开关脚本是否运行,抢完票后记得从Tampermonkey关掉脚本,不然浏览其他表演信息可能直接进入支付宝付账界面。

bc854dd0cbc4e2b28c120e51a1226535.png

使用步骤

1. 用Chrome浏览器打开Tampermonkey官网,点击按钮下载安装

1826349786e3388adaead672824bc5aa.png

2. 关注公众号,发送dmtk取得脚本地址

1a5c45d000be3bc7a6648623370af996.png

3. 通过地址打开greasy fork的页面,点击安装按钮自动跳转到Tampermonkey

af8f07d8ca563cf63819e4f67679d66b.png

4. 点击安装按钮

cfc1f4e1e388c48608e8afe9e559e586.png

5. 打开大麦网的页面,现在应该就可以看到按钮和提示了

9a50a7f00e5fbdd4d5f54d7abb979024.png

6. 根据提示修改「大麦抢票-选场次票价人数」中people_num为相应人数

5edb9f3743c707565e454e08c18dfb6a.png

7. 刷新页面加载新版脚本

8. 点击想要的场次,票价

9. 点击“开始抢票”

10.等待提示音响起

11.支付宝付款

12.抢票成功~

96d76be893d49a323695bbb94d2abe2c.png

如果报错

1. 可以打开开发者工具,如果报错一般是因为加载速度有点慢,可以适当放慢页面刷新速度或者换成更快的网络。

b2f37dff0996b9b46b480fab4e181c1d.png

2. 如果出错建议运行前先清除localStorage中的isRunning。然后重新加载页面。

dcb0f95438d266f58c5725153ec5068b.png

怎么写一个抢票脚本

开始前的准备:

  • 安装浏览器,比较推荐Chrome

  • 安装Tampermonkey (详情见「从安装Tampermonkey到成功抢到演唱会门票」) 

  • 知道一点JavaScript

  • 看看大麦网演唱会的网页是什么结构

观察大麦网购票流程

随便选一个演唱会页面看看。

d1419e88531b0b8cfc221e4bf2184d4f.png

c972f114bf29079979a06ad49dbabdb6.png

观察大麦网演唱会购买网页我们可以发现当演唱会有票的时候,我们可以选择场次,选择票档,选择数量,点击「立即购买」(上图是预定票所以是「立即预订」),然后会跳转到确认页面,需要我们选择地址,观演人,支付方式然后按下按钮进行预订。如果只有一个默认地址,在确认页面实际需要我们做的只是点击选中观演人然后提交订单。

当票已经卖光或者还没有开始销售的时候按钮上的文字是「提交缺货登记」,「提交开售登记」,并且没有选择数量的地方。

66ebdb72f5cbc7480226a162e52a29f2.png

baa528621501a4e1bed7ce5e4517a4f4.png

思考抢票脚本流程

  1. 用户登录,填写地址,观演人信息

  2. 用户手动点击选择场次,票档 (为什么没有数量?因为需要抢票的页面没有选择数量的地方),在脚本中修改数量

  3. 用户点击「开始抢票」,脚本读取当前选择的场次,票档,

  4. 刷新页面,脚本点击相应场次,票档

  5. 检查有没有调节数量的控件出现,如果没有,回到4

  6. 根据脚本中数量调成数量控件

  7. 检查购买按钮上是否是「立即购买」字样,如果不是,回到4

  8. 点击「立即购买」按钮,跳转到确认页面

  9. 选择观演人

  10. 点击「同意以上协议并提交订单」 (同时发出声音提醒用户)

  11. 支付宝付款

  12. 成功抢到票~

需要我们写的是2-10的部分。Tampermonkey会根据url判断执行什么脚本,所以我们可以写两个文件。

大麦抢票-选场次票价人数 2-8 

大麦抢票-确认 9-10

具体写法

大麦抢票-确认

从逻辑上来讲应该先写「大麦抢票-选场次票价人数」,但是「大麦抢票-确认」简单很多。所以先写这部分吧。

9d0ec8238297f1ea2d0677634a4a21bb.png

点击新建之后会出现一个模版文件。不要删掉上方的注释,非常重要。

// ==UserScript==// @name         New Userscript// @namespace    http://tampermonkey.net/// @version      0.1// @description  try to take over the world!// @author       You// @match        https://www.example.com// @grant        none// ==/UserScript==

具体每个字段的含义可以查询Tampermonkey官网。

// ==UserScript==// @name         大麦抢票-确认// @namespace    https://www.jwang0614.top/scripts// @version      0.1// @description  辅助购买大麦网演唱会门票// @author       Olivia Wang// @match        https://buy.damai.cn/orderConfirm*// @grant        none// ==/UserScript==

对我们来说最重要的是@match。其他@name,@description之类怎么填对我们要写的这个脚本执行都没有太大影响。@namespace是用来在@name相同时区分脚本的,可以用任何独特字符串,不过一般用自己个人主页url的比较多。

@match的重点是最后的*号通配符,这样只要url前面包含https://buy.damai.cn/orderConfirm, 无论Confirm之后跟的是什么有多长都能匹配上。不同网页的脚本@match的字符所规定的匹配规则会有变化。

具体代码:

(function() {    'use strict';    console.log("confirm");    // 点击观演人    var person = document.querySelector('#confirmOrder_1 > div.dm-ticket-buyer > div.ticket-buyer-select > div.next-row.next-row-no-padding.buyer-list > div > label > span.next-checkbox.isFirefox > span');    if (person) {        person.click();    }    // 播放提示音    var audio = new Audio("http://audio.marsupialgurgle.com/audio/successtrumpet.mp3");    audio.play();    // 提交订单    document.querySelector('#confirmOrder_1 > div.submit-wrapper > button').click();})();

虽然应该先成功提交再放庆祝提示音,但是点击提交后页面就跳转到支付宝了,所以这里是先播放提示音再点击提交订单。

有的确认页不需要选择观演人,所以要做个判断,不然在这一步会报错。

querySelector的那一长串直接用Chrome的开发者工具就可以获得:

a682135d30f34570eb43d396e8f881b6.png

点击红框中的按钮,然后在页面中点击选中你需要查看的元素,html中相关的元素会高亮显示。右键相应的html元素,选择复制selector,就可以得到那一长串字符了。

用document.querySelector就可以获取相应元素。

需要注意的是有些页面中元素会有变化,比如多一个少一个场次或者多一个少一个div什么的,直接复制的selector字符串可能含有类似:nth-child(6)的部分,这个数字可能会有变化,需要找到更加有普遍性的写法。比如根据有唯一classname的sibling节点定位之类的,大家可以多检查一下看看不同状态不同网页上selector是不是都能适用。

大麦抢票-选场次票价人数

还是以李荣浩的演唱会页面为例,url是https://detail.damai.cn/item.htm?spm=a2oeg.home.card_0.ditem_0.4b2a23e1sftIEo&id=594350362632。所以@match 写成 https://detail.damai.cn/*就可以了。

我们可以把这个脚本分成几个部分

  1. UI

    1. 开始抢票按钮

    2. 结束抢票按钮

    3. 提示

  2. 从页面获取用户输入场次票价

  3. 刷新

  4. 根据用户输入填入数据

  5. 判断能不能购买,如果可以点击按钮,如果不行再次刷新

LocalStorage

我们希望能刷新后保存用户场次票价人数信息,所以用到LocalStorage。

var people_num = 2;var isRunning = false;var storage = window.localStorage;storage.setItem("people_num", people_num);storage.setItem("isRunning", isRunning);

还没开票的页面也没有数量控件,所以通过脚本控制购票数量,储存到LocalStorage中。isRunning用来判断是不是在运行。

有的浏览器可能不太支持LocalStorage,可以在程序最开始判断一下.

if(!window.localStorage){    alert('不支持这个浏览器,请换成Chrome或者Safari。');}

UI

添加两个固定在页面上的按钮和一个提示栏。比如「开始抢票」按钮

// 创建一个p标签var start = document.createElement("P");// 添加文字start.appendChild(document.createTextNode("开始抢票"));// 设置格式,位置start.style.lineheight="50px";start.style.color="white";start.style.fontSize="30px";start.style.padding="10px 20px";start.style.background="green";start.style.position="fixed";start.style.right="30px";start.style.top="100px";// 保持在最上方start.style.zIndex="10000";// 获取dom中body元素var container = document.querySelector('body');//start按钮添加到dom中container.appendChild(start);
从页面获取用户选择的场次,票价信息
function get_numbers_from_page() {    var event_selections = document.querySelectorAll('body > div.perform > div > div.flex1 > div.hd > div > div.order > div.perform__order__box > div.perform__order__select.perform__order__select__performs > div.select_right > div > div');    // 这里就用了sibling node定位 div.perform__desc__info + div    //+ div” 代表下一个div sibling    var price_selections = document.querySelectorAll('body > div.perform > div > div.flex1 > div.hd > div > div.order > div.perform__order__box > div.perform__desc__info + div > div.select_right > div > div');    for (var i= 0;i < event_selections.length;i++) {        // 通过class中是否含有active判断用户选择的是第几个选项,将结果数字保存在本地存储中        if (event_selections[i].classList.contains("active")) {            storage.setItem("event_ele_num", i);        }    }    for (var j= 0;j < price_selections.length;j++) {        if (price_selections[j].classList.contains("active")) {            storage.setItem("price_ele_num", j);        }    }}

一段时间后刷新页面

function timedRefresh(timeoutPeriod) {    window.setTimeout("location.reload(true);",timeoutPeriod);}

填写数据,判断当前能不能购买

function set_up_check_page() {    // 从storage中获取场次,票价,数量信息    var event_ele_num = storage.getItem("event_ele_num");    var price_ele_num = storage.getItem("price_ele_num");    var people_num = storage.getItem("people_num");    // 为了更直观地表现出“程序正在运行”,我把网页背景换了一个颜色    if (storage.getItem("isRunning") == "true") {        document.querySelector('body > div.perform').style.background="darksalmon";    }    // 获取所有的场次元素,点击相应元素选择    var event_selections = document.querySelectorAll('body > div.perform > div > div.flex1 > div.hd > div > div.order > div.perform__order__box > div.perform__order__select.perform__order__select__performs > div.select_right > div > div');    event_selections[event_ele_num].click();    var price_selections = document.querySelectorAll('body > div.perform > div > div.flex1 > div.hd > div > div.order > div.perform__order__box > div.perform__desc__info + div > div.select_right > div > div');    price_selections[price_ele_num].click();    // 判断有没有数量控件,如果有设定数量,如果没有继续刷新    var people_selection = document.querySelector(".cafe-c-input-number-input");    if (people_selection) {        // 这里我用的是点击增加按钮,其实可以通过修改value的值实现        var people_inc_btn = document.querySelector('body > div.perform > div > div.flex1 > div.hd > div > div.order > div.perform__order__box > div:nth-child(6) > div.number_right > div > div > a.cafe-c-input-number-handler.cafe-c-input-number-handler-up');        for (var i =1; i < people_num; i++) {            people_inc_btn.click();        }        // 判断有没有“立即购买“按钮        var btn = document.querySelector("body > div.perform > div > div.flex1 > div.hd > div > div.order > div.perform__order__box > div:last-child > div");        if (btn) {            if (btn.innerText == "立即购买") {                // 点击立即购买按钮跳转到确认页                storage.removeItem("isRunning");                storage.removeItem("price_ele_num");                storage.removeItem("event_ele_num");                storage.removeItem("people_num");                storage.clear();                btn.click();            }        }    }    // 如果正在抢票,0.4秒后刷新页面    if (storage.getItem("isRunning") == "true") {        timedRefresh(400);    }}

通过按钮控制脚本的开始和停止

// 开始抢票按钮start.onclick = function() {    console.log('开始抢票!');    document.querySelector('body > div.perform').style.background="darksalmon";    storage.setItem("isRunning", true);    get_numbers_from_page();    timedRefresh(600);};// 停止抢票按钮stop.onclick = function() {    alert('停止抢票!');    document.querySelector('body > div.perform').style.background="white";    //storage.setItem("isRunning", false);    storage.removeItem("isRunning");};

因为怕刷新太快来不及按「停止抢票」,我加入了快捷键。每个字母的keyCode可以在网上找到。

document.onkeydown = function() {    var oEvent = window.event;    if (oEvent.keyCode == 69 && oEvent.ctrlKey) {        //alert("你按下了ctrl+E");        // start        start.click();    }else if (oEvent.keyCode == 84 && oEvent.ctrlKey) {        //alert("你按下了ctrl+T");        // stop        stop.click();    }}

刷新

function reload_page() {    // console.log("reload");    window.setTimeout(set_up_check_page,800);}

组合

将以上内容补全完整组合到一起就可以啦,完整的代码请关注下方公众号,输入dmtk获取下载地址。

1a5c45d000be3bc7a6648623370af996.png

有什么问题和意见欢迎大家在下面给我留言~如果脚本运行出了什么问题也可以告诉我,我看看能不能改一改。

3ed328af5afcd9bb1c8b00c747757edc.png

bbc980403b6ae65d6985b8f561366d3b.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/196642
推荐阅读
相关标签
  

闽ICP备14008679号