国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python + selenium + requests實(shí)現(xiàn)12306全自動(dòng)搶票及驗(yàn)證碼破解加自動(dòng)點(diǎn)擊功能

2020-01-04 14:00:10
字體:
供稿:網(wǎng)友

測(cè)試結(jié)果: 

Python,selenium,requests,12306,全自動(dòng)搶票,驗(yàn)證碼

整個(gè)買票流程可以再快一點(diǎn),不過為了穩(wěn)定起見,有些地方等待了一些時(shí)間

完整程序,拿去可用

整個(gè)程序分了三個(gè)模塊:購票模塊(主體)、驗(yàn)證碼識(shí)別模塊、余票查詢模塊

購票模塊:

from selenium import webdriverfrom selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException, ElementNotVisibleExceptionimport timeimport requestsfrom urllib.parse import urlencodefrom pyquery import PyQuery as pqfrom check_ticket import Checkfrom verify import Codeimport jsonclass Buy_Ticket():  def __init__(self, start_station, end_station, date, username, password, purpose):    self.num = 1    self.start = start_station    self.end = end_station    self.date = date    self.username = username    self.password = password    self.purpose = purpose    self.login_url = 'https://kyfw.12306.cn/otn/login/init'    self.ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init'  def login(self):    browser.get(self.login_url)    try:      input_name = browser.find_element_by_id('username')      input_pd = browser.find_element_by_id('password')      button = browser.find_element_by_id('loginSub')      time.sleep(1)      input_name.send_keys(self.username)      input_pd.send_keys(self.password)      c = Code(browser)    #調(diào)用驗(yàn)證碼識(shí)別模塊      c.main()      button.click()      time.sleep(2)      #等待頁面跳轉(zhuǎn),如果驗(yàn)證碼識(shí)別錯(cuò)誤,就執(zhí)行下面的while語句      while browser.current_url == self.login_url + '#':        c = Code(browser)        c.main()        button.click()        time.sleep(2)      #self.get_passenger()      self.check()    except NoSuchElementException:      self.login()  def check(self):    #調(diào)用余票查詢模塊    check = Check(self.date, self.start, self.end, self.purpose)    start_end = check.look_up_station()    self.num = check.get_info()    #cookie的添加,json.dumps把以漢字形式呈現(xiàn)的起始、終點(diǎn)站轉(zhuǎn)化成unicode編碼,可在審查元素里查看cookie    browser.add_cookie({'name':'_jc_save_fromStation', 'value':json.dumps(self.start).strip('"').replace('//', '%') + '%2C' + start_end[0]})    browser.add_cookie({'name':'_jc_save_toStation', 'value':json.dumps(self.end).strip('"').replace('//', '%') + '%2C' + start_end[1]})    browser.add_cookie({'name':'_jc_save_fromDate', 'value':self.date})    browser.get(self.ticket_url)    if self.purpose == '學(xué)生':      btn = browser.find_element_by_id('sf2')      time.sleep(1)      btn.click()    button = browser.find_element_by_id('query_ticket')    time.sleep(1)    button.click()  def book_ticket(self):    print('開始預(yù)訂車票...')    #先查找出所有車次對(duì)應(yīng)的預(yù)訂按鈕,再根據(jù)余票查詢模塊返回的車次序號(hào),點(diǎn)擊相應(yīng)的預(yù)訂按鈕    button = browser.find_elements_by_class_name('btn72')    button[self.num-1].click()    time.sleep(3)    button2 = browser.find_element_by_id('normalPassenger_0') #按實(shí)際情況,可自行修改,這里就選擇的第一個(gè)常用聯(lián)系人,                                  #第二個(gè)是normalPassenger_1,依此類推    button2.click()    button3 = browser.find_element_by_id('submitOrder_id')    time.sleep(1)    button3.click()    time.sleep(3) #等待頁面加載完畢,不然后面可能會(huì)報(bào)錯(cuò),等待時(shí)間自行決定    try:      button4 = browser.find_element_by_id('qr_submit_id')      button4.click()    except ElementNotVisibleException:      button4 = browser.find_element_by_id('qr_submit_id')      button4.click()    print('車票預(yù)定成功!請(qǐng)?jiān)?0分鐘內(nèi)完成付款!')  def main(self):    self.login()    self.book_ticket()if __name__ == '__main__':  begin = time.time()  browser = webdriver.Chrome()  b = Buy_Ticket('上海', '重慶', '2018-09-18', '賬號(hào)', '密碼', 'ADULT') #賬號(hào)、密碼自行修改  b.main()  end = time.time()  print('總耗時(shí):%d秒' % int(end-begin))  #browser.close()

驗(yàn)證碼識(shí)別模塊:

import requestsfrom PIL import Imagefrom selenium.webdriver import ActionChainsimport timefrom io import BytesIOclass Code():  def __init__(self, browser):    self.browser = browser    self.verify_url = 'http://littlebigluo.qicp.net:47720/'   #驗(yàn)證碼識(shí)別網(wǎng)址,返回識(shí)別結(jié)果    #確定驗(yàn)證碼的位置  def get_position(self):    time.sleep(3)    element = self.browser.find_element_by_class_name('touclick-img-par')    time.sleep(2)    location = element.location    size = element.size    position= (location['x'], location['y'], location['x'] + size['width'], location['y'] + size['height'])    return position    #截取整個(gè)網(wǎng)頁頁面  def get_screenshot(self):    screenshot = self.browser.get_screenshot_as_png()    screenshot = Image.open(BytesIO(screenshot))    return screenshot    #從截取的網(wǎng)頁,裁剪出驗(yàn)證碼圖片,并保存到本地  def get_touclick_img(self, name = 'captcha.png'):    position = self.get_position()    print('驗(yàn)證碼的位置:', position)    screenshot = self.get_screenshot()    captcha = screenshot.crop(position)    captcha.save('captcha.png')    #驗(yàn)證碼解析  def parse_img(self):    files = {'file': open('captcha.png', 'rb')}       #打開保存到本地的驗(yàn)證碼圖片    response = requests.post(self.verify_url, files=files)    num = response.text.split('<B>')[1].split('<')[0]    print('驗(yàn)證碼識(shí)別成功!圖片位置:%s' % num)    try:      if int(num):        return [int(num)]    except ValueError:      num = list(map(int,num.split()))      return num    #識(shí)別結(jié)果num都以列表形式返回,方便后續(xù)驗(yàn)證碼的點(diǎn)擊    #實(shí)現(xiàn)驗(yàn)證碼自動(dòng)點(diǎn)擊  def move(self):    num = self.parse_img()    try:      element = self.browser.find_element_by_class_name('touclick-img-par')      for i in num:        if i <= 4:          ActionChains(self.browser).move_to_element_with_offset(element,40+72*(i-1),73).click().perform()        else :          i -= 4          ActionChains(self.browser).move_to_element_with_offset(element,40+72*(i-1),145).click().perform()    except:      print('元素不可選!')  def main(self):    self.get_touclick_img()    self.move()

余票查詢模塊:

 

import requestsfrom urllib.parse import urlencodeclass Check():  def __init__(self, date, start, end, purpose):    self.base_url = 'https://kyfw.12306.cn/otn/leftTicket/queryA?'    self.url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9018'    self.date = date    self.start_station = start    self.end_station = end    if purpose == '學(xué)生':      self.purpose = '0X00'    else:      self.purpose = purpose    #查找出車站的英文簡(jiǎn)稱,用于構(gòu)造cookie、完整的余票查詢鏈接  def look_up_station(self):    response1 = requests.get(self.url)    a = response1.text.split('@')    a.pop(0)    for each in a:      i = each.split('|')      if self.start_station == i[1]:        self.start_station = i[2]      elif self.end_station == i[1]:        self.end_station = i[2]    return [self.start_station, self.end_station]  def get_info(self):    start_end = self.look_up_station()    #構(gòu)造請(qǐng)求參數(shù)    data = {    'leftTicketDTO.train_date':self.date,    'leftTicketDTO.from_station':start_end[0],    'leftTicketDTO.to_station':start_end[1],    'purpose_codes':self.purpose    }    url = self.base_url + urlencode(data)    response = requests.get(url)    json = response.json()    maps = json['data']['map']    count = 0    #用于對(duì)車次編號(hào)           for each in json['data']['result']:      count += 1      s = each.split('|')[3:]      info = {      'train':s[0],      'start_end':maps[s[3]] + '-' + maps[s[4]],      'time':s[5] + '-' + s[6],      '歷時(shí)':s[7],      '一等座':s[-5],      '二等座':s[-6]      }      try:        #余票的結(jié)果有3種:有、一個(gè)具體的數(shù)字(如:18、6等)、無,判斷如果余票是有或者一個(gè)具體的數(shù)字就直接輸出對(duì)應(yīng)的車次信息,然后返回        if info['二等座'] == '有' or int(info['二等座']):             print('[%d]' % count, info)          return count      except ValueError:        continue   

總結(jié)

以上所述是小編給大家介紹的Python + selenium + requests實(shí)現(xiàn)12306全自動(dòng)搶票及驗(yàn)證碼破解加自動(dòng)點(diǎn)擊功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)VEVB武林網(wǎng)網(wǎng)站的支持!


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到python教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宁津县| 简阳市| 乾安县| 青海省| 沁阳市| 西峡县| 东辽县| 金门县| 边坝县| 达孜县| 隆回县| 南平市| 苍山县| 连江县| 丰台区| 禹城市| 花莲县| 两当县| 纳雍县| 义乌市| 和政县| 澎湖县| 宁河县| 县级市| 河津市| 泉州市| 康马县| 都兰县| 华亭县| 锦州市| 长兴县| 杭锦后旗| 通渭县| 龙陵县| 五峰| 崇阳县| 沙田区| 博罗县| 乡城县| 云南省| 西和县|