├── Automatic_ticket_purchase.py ├── README.md ├── chromedriver └── requirements.txt /Automatic_ticket_purchase.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import re 5 | import time 6 | import pickle 7 | from tkinter import * 8 | from time import sleep 9 | from selenium import webdriver 10 | 11 | from selenium.webdriver.common.by import By 12 | from selenium.webdriver.common.keys import Keys 13 | from selenium.webdriver.support.ui import WebDriverWait 14 | from selenium.common.exceptions import TimeoutException 15 | from selenium.webdriver.support import expected_conditions as EC 16 | from selenium.webdriver.common.action_chains import ActionChains 17 | 18 | 19 | #大麦网主页 20 | damai_url="https://www.damai.cn/" 21 | #登录页 22 | login_url="https://passport.damai.cn/login?ru=https%3A%2F%2Fwww.damai.cn%2F" 23 | #抢票目标页 24 | # target_url="https://detail.damai.cn/item.htm?spm=a2oeg.search_category.0.0.41604d150fzHFD&id=593516280422&clicktitle=2019MDSK%E9%9F%B3%E4%B9%90%E8%8A%82%E6%AD%A6%E6%B1%89%E7%AB%99" 25 | #选座类型页面 26 | target_url="https://detail.damai.cn/item.htm?spm=a2oeg.search_category.0.0.51ce6bffe7kiLU&id=593089517773&clicktitle=2019%20DOTA2%20%E5%9B%BD%E9%99%85%E9%82%80%E8%AF%B7%E8%B5%9B" 27 | 28 | name = "123" 29 | phone = "123" 30 | privilege_code = "123" 31 | 32 | class Concert(object): 33 | def __init__(self): 34 | 35 | self.status = 0 #状态,表示如今进行到何种程度 36 | self.login_method = 1 #{0:模拟登录,1:Cookie登录}自行选择登录方式 37 | 38 | def set_cookie(self): 39 | self.driver.get(damai_url) 40 | print("###请点击登录###") 41 | while self.driver.title.find('大麦网-全球演出赛事官方购票平台')!=-1: 42 | sleep(1) 43 | print("###请扫码登录###") 44 | while self.driver.title=='中文登录': 45 | sleep(1) 46 | print("###扫码成功###") 47 | pickle.dump(self.driver.get_cookies(), open("cookies.pkl", "wb")) 48 | print("###Cookie保存成功###") 49 | self.driver.get(target_url) 50 | 51 | def get_cookie(self): 52 | try: 53 | cookies = pickle.load(open("cookies.pkl", "rb"))#载入cookie 54 | for cookie in cookies: 55 | cookie_dict = { 56 | 'domain':'.damai.cn',#必须有,不然就是假登录 57 | 'name': cookie.get('name'), 58 | 'value': cookie.get('value'), 59 | "expires": "", 60 | 'path': '/', 61 | 'httpOnly': False, 62 | 'HostOnly': False, 63 | 'Secure': False} 64 | self.driver.add_cookie(cookie_dict) 65 | print('###载入Cookie###') 66 | except Exception as e: 67 | print(e) 68 | 69 | def login(self): 70 | if self.login_method==0: 71 | self.driver.get(login_url) #载入登录界面 72 | print('###开始登录###') 73 | 74 | elif self.login_method==1: 75 | if not os.path.exists('cookies.pkl'): #如果不存在cookie.pkl,就获取一下 76 | self.set_cookie() 77 | else: 78 | self.driver.get(target_url) 79 | self.get_cookie() 80 | 81 | 82 | def enter_concert(self): 83 | print('###打开浏览器,进入大麦网###') 84 | self.driver = webdriver.Chrome('./chromedriver') #默认Chrome浏览器 85 | # self.driver.maximize_window() #最大化窗口 86 | self.login() #先登录再说 87 | self.driver.refresh() #刷新页面 88 | self.status = 2 #登录成功标识 89 | print("###登录成功###") 90 | 91 | def add_code(self): 92 | print('###添加特权码###') 93 | self.driver.find_element_by_id('privilege_val').send_keys(privilege_code) 94 | self.driver.find_element_by_xpath('//html//body//div[2]//div//div[1]//div[1]//div//div[2]//div[3]//div[3]//div[1]//button').click() #点击确定 特权码 95 | 96 | def choose_ticket(self): 97 | if self.status == 2: #登录成功入口 98 | self.num = 1 #第一次尝试 99 | 100 | print("="*30) 101 | print("###开始进行日期及票价选择###") 102 | while self.driver.title.find('确认订单') == -1: #如果跳转到了订单结算界面就算这步成功了,否则继续执行此步 103 | self.add_code() # 添加特权码 104 | try: 105 | self.driver.find_element_by_class_name('cafe-c-input-number-handle-up').click() #购票数加1 106 | except Exception as e: 107 | pass 108 | 109 | # self.driver.find_elements_by_xpath('//html//body//div[@class = "perform__order__price"]//div[2]//div//div//a[2]')[0].click() #购票数+1(若需要) 110 | self.driver.find_elements_by_xpath('//div[@class = "perform__order__select perform__order__select__' 111 | 'performs"]//div[2]//div//div[3]')[0].click() #默认购票日期的选择,x为日期的选择,1,2,3.... 112 | cart = self.driver.find_element_by_class_name('perform') #获得选票界面的表单值 113 | 114 | # try:各种按钮的点击, 115 | buybutton = self.driver.find_element_by_class_name('buybtn').text 116 | try: 117 | buybutton = self.driver.find_element_by_class_name('buybtn').text 118 | if buybutton == "即将开抢": 119 | self.status=2 120 | self.driver.get(target_url) 121 | print('###抢票未开始,刷新等待开始###') 122 | continue 123 | 124 | elif buybutton == "立即预定": 125 | self.driver.find_element_by_class_name('buybtn').click() 126 | self.status = 3 127 | self.num = 1 128 | elif buybutton == "立即购买": 129 | self.driver.find_element_by_class_name('buybtn').click() 130 | self.status = 4 131 | 132 | #选座购买暂时无法完成自动化 133 | elif buybutton == "选座购买": 134 | self.driver.find_element_by_class_name('buybtn').click() 135 | self.status = 5 136 | 137 | elif buybutton == "提交缺货登记": 138 | print('###抢票失败,请手动提交缺货登记###') 139 | break 140 | 141 | except: 142 | print('###未跳转到订单结算界面###') 143 | 144 | title = self.driver.title 145 | if title =="确认订单" : 146 | self.check_order() 147 | 148 | #若是选座购买,自行选座 149 | elif self.status == 5 : 150 | print("###请自行选择位置和票价###") 151 | break 152 | 153 | # if title !="确认订单" : #如果前一次失败了,那就刷新界面重新开始 154 | # self.status=2 155 | # self.driver.get(target_url) 156 | # print('###抢票失败,从新开始抢票###') 157 | 158 | 159 | def check_order(self): 160 | if self.status in [3,4]: 161 | print('###开始确认订单###') 162 | print('###默认购票人信息###') 163 | try: 164 | #姓名和电话的填写,这是绝对路径,由于大麦网目标页会更新,出现问题修改xpath即可 165 | 166 | self.driver.find_elements_by_xpath('//div[@class = "w1200"]//div[@class = "delivery-form"]//div[1]//div[2]//span//input')[0].send_keys(name) 167 | time.sleep(0.5) 168 | self.driver.find_elements_by_xpath('//div[@class = "w1200"]//div[@class = "delivery-form"]//div[2]//div[2]//span[2]//input')[0].send_keys(phone) 169 | time.sleep(0.5) 170 | except Exception as e: 171 | print("###填写确认订单信息时,联系人手机号填写失败###") 172 | print(e) 173 | try: 174 | #默认选第一个购票人信息 175 | self.driver.find_elements_by_xpath('//div[@class = "w1200"]//div[@class = "ticket-buyer-select"]//div//div[1]//span//input')[0].click() #观影人1 176 | #选第二个购票人信息(若购买多张票时需要开启此选项,增加购票人信息) 177 | # self.driver.find_elements_by_xpath('//div[@class = "w1200"]//div[@class = "ticket-buyer-select"]//div//div[2]//span//input')[0].click() #观影人2 178 | 179 | except Exception as e: 180 | print("###购票人信息选中失败,自行查看元素位置###") 181 | print(e) 182 | 183 | print('###不选择订单优惠###') 184 | print('###请在付款完成后下载大麦APP进入订单详情页申请开具###') 185 | 186 | # 最后一步提交订单 187 | 188 | time.sleep(1) # 太快会影响加载,导致按钮点击无效 189 | self.driver.find_elements_by_xpath('//div[@class = "w1200"]//div[2]//div//div[9]//button[1]')[0].click() 190 | 191 | # try: 192 | # element = WebDriverWait(self.driver, 5).until(EC.title_contains('支付宝 - 网上支付 安全快速!')) 193 | # self.status=6 194 | # print('###成功提交订单,请手动支付###') 195 | # except: 196 | # print('###提交订单失败,请查看问题###') 197 | 198 | #若出现异常则关闭开启的浏览器及驱动,建议使用时注释掉,否则异常发生会关闭打开的浏览器 199 | def finish(self): 200 | self.driver.quit() 201 | 202 | if __name__ == '__main__': 203 | try: 204 | con = Concert() #具体如果填写请查看类中的初始化函数 205 | con.enter_concert() 206 | con.choose_ticket() 207 | 208 | except Exception as e: 209 | print(e) 210 | #con.finish() 211 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 大麦网演唱会抢票程序---参考自github 作者:MakiNaruto 地址:https://github.com/MakiNaruto/Automatic_ticket_purchase 2 | 对该源码做了稍许修改,去掉了多余的依赖文件,直接修改代码里的购买页地址、关键人信息即可进行抢票。 3 | 4 | ## 准备工具 5 | * Python3.6 6 | * Selenium 7 | * 本人用的chrome浏览器(可以改用火狐、IE等),需要下载ChromeDriver包及配置 http://chromedriver.storage.googleapis.com/index.html 8 | * 根据你用的chrome版本,自行寻找对应的chromeDrive包,并替换已有的chromedriver版本 9 | * 请自己填写你的特权码 10 | * 自行寻找使用方法,这里不就不细述了。 11 | 12 | 13 | 最后成功测试运行时间:2019-05-08。此方法太过于依赖页面源码的元素ID、xpath、class,若相应的绝对路径寻找不到会出现问题。建议自己先测试一遍,自行定位相应的绝对路径或用更好的定位方法替代。 14 | 15 | -------------------------------------------------------------------------------- /chromedriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diw1/Automatic_ticket_purchase/23beb4bb9386e6ed9860016cdcd26d4d3621b0b1/chromedriver -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | selenium 2 | tkinter --------------------------------------------------------------------------------