中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python實現12306搶票及自動郵件發送提醒付款功能

發布時間:2020-09-22 13:17:50 來源:腳本之家 閱讀:245 作者:薄荷總是那么清新 欄目:開發技術

#寫在前面,這個程序我已經弄出來了,但是因為黃牛泛濫以及懶人太多,整個程序的代碼就不貼出來了,這里純粹就是技術交流。

只做技術交流、、、、、

python實現12306搶票及自動郵件發送提醒付款功能 python實現12306搶票及自動郵件發送提醒付款功能

嗯,程序結束后,自己還是得手動付款。

廢話不多說,下面就直接開始技術主要部分闡述。

先講理論部分:首先我們需要代碼實現一個瀏覽器功能,那么模塊基本上可以確定urllib.parse、urllib.request,這兩個包都是和網址有關的模塊,那么咱們去登錄一個網址,特別是有驗證碼這些的網址,我們登錄進去是不是就行了?答案是對的,但是我們用代碼實現的話,這個網址可能每次都有可能被代碼去請求,那么服務器怎么知道我們是一個人,而不是多個瀏覽器不同的用戶呢?

此時cookie就非常重要了,在代碼中設置好cookie,那么對方服務器自然就知道我們是一個人,比較服務器都是這么區分的。python3中 cookie這個功能是封裝在http.cookiejar這個模塊之內。好了,代碼如下:

# coding=utf-8
# author: Jason
# time:2018/1/16 20:00:00
#version:1.0
import urllib.request as ul
import urllib.parse as uz
import http.cookiejar as cookielib
from json import loads
c=cookielib.LWPCookieJar()#先把cookie對象存儲為cookiejar的對象
cookie = ul.HTTPCookieProcessor(c)#把cookiejar對象轉換為一個handle
opener = ul.build_opener(cookie)#建立一個模擬瀏覽器,需要handle作為參數
ul.install_opener(opener)#安裝一個全局模擬瀏覽器,代表無論怎么訪問都是一個瀏覽器操作而不是分開獲取驗證碼等msg

好了,如此一來,我們代碼的初步實現已經完成,接下來就是進入網絡分析部分

首先可以使用google瀏覽器或者搜狗瀏覽器(本人用的搜狗),打開F12,也就是開發者模式,登錄12306的登錄地址 https://kyfw.12306.cn/otn/login/init

python實現12306搶票及自動郵件發送提醒付款功能

兩個紅圈中第二個是驗證碼來源,此時我們只需要記錄這個網頁(點進去)的詳細情況,寫入代碼當中,python3中urllib.request這個模塊打開既可

python實現12306搶票及自動郵件發送提醒付款功能

如此便是驗證碼來源,那么如何用代碼捕捉呢?首先我們可以先亂輸入密碼,亂點驗證碼,然后我們直接點擊登錄

python實現12306搶票及自動郵件發送提醒付款功能

多了一個很奇妙的東西,此時,這里就是驗證碼驗證的網址,那么我們是不是應該記錄下來呢?很簡單,到Headers里面就全都看得到了

python實現12306搶票及自動郵件發送提醒付款功能

上面那個是服務器驗證網址,下面就是我們回復給他的東西,那么那個163,121其實就是我亂點的驗證碼坐標了。至于為啥是坐標,因為它是用鼠標去點圖片,那么他只可能是記錄坐標,除非他自己搞了一套人工智能驗證圖片,但基于他幾年前就這么玩了,人工智能根本沒有怎么開始,他自然只能是最原始的技術而已。

那么這代表了他是先驗證驗證碼,那么驗證密碼的在哪?自然是需要驗證碼這關能過,那我們輸一個正確的驗證碼,再寫個錯密碼,登錄

python實現12306搶票及自動郵件發送提醒付款功能

此時可以看到,和驗證碼一樣的方法,我們的回復與驗證都在這幾個圈了,還記得上面驗證碼失敗的時候回復給我們的code是不是有個數字?這個也很重要,那么可以看看我們的驗證成功的驗證碼返回給我們的是什么東西

python實現12306搶票及自動郵件發送提醒付款功能

這次我們看到了,驗證碼成功,顯示是4,好,那我們不就可以進行條件判斷了么?

那么如何打開一個網址然后把我們點的東西一起發過去呢?上代碼

headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'}#先寫個頭,表示我這是瀏覽器用戶登錄而不是代碼登錄,如果不寫,代碼默認用的簽名之類的是編程語言的標識,這樣對方服務器很容易就發現你是個腳本了
def get_code():#獲取驗證碼的步驟
  req = ul.Request('https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.6758635422370105')
  req.headers = headers
  code_file = opener.open(req).read()#此時為瀏覽器的open而不再是ul.urlopen,下同
  with open(r'C:\Users\Administrator\Desktop\12306自動搶票\code.png','wb')as f:
    f.write(code_file)

把驗證碼直接下載后方電腦上,后面要坐標只需要打開這個圖既可輸入,坐標的輸入方式我用字典表示給大家看{1:(45,45)}{2:(120,45)}{3:(180,45)}{4:(255,45)}{5:(45,120)}{6:(120,120)}{7:(180,120)}{8:(255,120)}

根據這個驗證碼的排序,我相信讀者應該知道順序怎么來的吧,比較坐標就能懂了。

繼續

def main_():
  get_code()
  code = input('輸入驗證碼:')
  req = ul.Request('https://kyfw.12306.cn/passport/captcha/captcha-check')
  req.headers = headers

  data = {
    'answer':code,
    'login_site':'E',
    'rand':'sjrand'
  }
  data = uz.urlencode(data).encode()#把字典轉換為URL query string,此時是str,要把它變為byts。

  html = opener.open(req,data= data).read().decode()#讀取出來是byts格式,轉換為‘utf-8(默認)
  print(html)
  result = loads(html)
  if result['result_code']=='4':
    print('驗證碼通過')
    rep = ul.Request('https://kyfw.12306.cn/passport/web/login')
    rep.headers = headers
    data = {'username':'這里就是你用戶名',
        'password':'這里就是你的密碼',
        'appid':'otn'
    }
    data = uz.urlencode(data).encode() #看到了嗎,這就是你給服務器回復的東西

    html1 = opener.open(rep,data = data ).read().decode()
    result1 = loads(html1)
    if result1['result_code'] == 0:
      print('賬戶密碼驗證通過')
    else:
      print(result1['result_message'])

  else:
    print('驗證碼校驗失敗,重來')


if __name__ == '__main__':
  main_()

此時,咱們就過了驗證碼密碼這一關,后面是不是又要查票?那么同樣的方法,我們就可以以此類推到最后一步,這里就不一一貼代碼了

ps:查代碼這幾步的信息可是很重要喔,我們要把它記錄好,并且這里面的信息包含了各種作為信息以及他們的順序,多測試幾次基本都能搞出來,這里就是提醒一點

python實現12306搶票及自動郵件發送提醒付款功能

找找規律,然后用split的方法完全就可以切割出來,然后一個循環,就可以得到第幾個元素是我們要的,那么后面就可以標志判斷返回值如果是無,就沒票可以繼續查詢,直到有票就可以下一步;

那么有票的話,后面一樣也是以此類推的方式,代碼我就不重現了,很簡單,我就把后面出現需要請求的網址都發出來供大家觀摩

查詢車票信息

url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT'%(train_data,from_station,to_station)
req = ul.Request('https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest')#確定訂單信息
req = ul.Request("https://kyfw.12306.cn/otn/confirmPassenger/initDc")#驗證訂單
req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs')#準備跨到下單中的過度
req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo')#檢查訂單信息
req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount')#信息提交給服務器,準備進入下單步驟
req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue')#正式進入下單步驟
req = ul.Request('https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random=%s&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN=%s'%(numb,time.time()))#下單確認中,此時這個網址一般是進行兩次訪問,不知為何,我還是做了兩次訪問,numb是前面查詢車票點擊預定回復我們的信息中的一條,有點難找喔,我曾經找了三天。。。當然是因為自己不仔細而已
zreq = ul.Request("https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue")#最后的結果回執,如果一切都順利,那么票就已經訂了。我一般是打印他返回的內容
'''
      zreq = ul.Request("https://kyfw.12306.cn/otn/confirmPassenger/resultOrderForDcQueue")
      zreq.headers = headers
      data ={"REPEAT_SUBMIT_TOKEN":"%s"%numb,
          "_json_att": "",
          "orderSequence_no":orderId
          }
      data = uz.urlencode(data).encode()
      html = opener.open(zreq,data=data).read().decode()
      result = loads(html)
      print('代碼全部過完,回去登錄下是否搞定')
      print(result)
      print(result['data']['submitStatus'])
      if result['data']['submitStatus'] == True:
        print('購票成功')
        return True
      else:
        print('購票失敗,重試其他列車')
        continue
'''
最終的回執代碼詳細 信息,讀者可以自己嘗試多次,得到自己的回復代碼確認是否購票成功,因為result['data']['submitStatus']==True只不過是確認訂單狀態而已,這個被我改動過,你可以多次嘗試

最后的最后,火車票預訂成功只有30分鐘支付時間,所以我為了防止訂好票但是我人不在,特意寫了qq郵件通知

qq郵件通知:

def email():#這是我訂票后給自己發郵件的函數
  import smtplib
  from email.mime.text import MIMEText
  import time
  text = '已經為%s搶到票,速度登錄12306付款,用戶名:%s,密碼:%s'%(NAME,username,password)
  msg = MIMEText(text, 'plain', 'utf-8')
  msg_From = '2059****16@qq.com'
  msg_To = '5043****75@qq.com'#是的,我有兩個qq,一個發一個收
  smtpSever = 'smtp.qq.com' # qq郵箱的smtp Sever地址
  smtpPort = '465' # 開放的端口
  sqm = 'q********eghe' # 在登錄smtp時需要login中的密碼應當使用授權碼而非賬戶密碼
  msg['from'] = msg_From
  msg['to'] = msg_To
  msg['subject'] = 'Python自動郵件-%s' % time.ctime()
  smtp = smtplib
  smtp = smtplib.SMTP_SSL()
  '''
  smtplib的connect(連接到郵件服務器)、login(登陸驗證)、sendmail(發送郵件)
  '''
  smtp.connect(smtpSever, smtpPort)
  smtp.login(msg_From, sqm)
  smtp.sendmail(msg_From, msg_To, str(msg))
  # s = smtplib.SMTP("localhost")
  # s.send_message(msg)
  smtp.quit()
  print('郵件已發送~你可以安心去玩了')
def emailforcode():#此函數是防止查詢有票但12306賬號掉線人不在無法訂票的提醒
  import smtplib
  from email.mime.text import MIMEText
  import time
  text = '%s賬號下線,速度登錄驗證12306' % NAME
  msg = MIMEText(text, 'plain', 'utf-8')
  msg_From = '205****516@qq.com'
  msg_To = '50****75@qq.com'
  smtpSever = 'smtp.qq.com' # qq郵箱的smtp Sever地址
  smtpPort = '465' # 開放的端口
  sqm = 'qowa*******ghe' # 在登錄smtp時需要login中的密碼應當使用授權碼而非賬戶密碼
  msg['from'] = msg_From
  msg['to'] = msg_To
  msg['subject'] = 'Python自動郵件-%s' % time.ctime()
  smtp = smtplib
  smtp = smtplib.SMTP_SSL()
  '''
  smtplib的connect(連接到郵件服務器)、login(登陸驗證)、sendmail(發送郵件)
  '''
  smtp.connect(smtpSever, smtpPort)
  smtp.login(msg_From, sqm)
  smtp.sendmail(msg_From, msg_To, str(msg))
  # s = smtplib.SMTP("localhost")
  # s.send_message(msg)
  smtp.quit()
  print('郵件已發送~')

如此就大功告成了。

不能發完整的代碼(本身目的就是為了技術交流而已,防止懶人盜碼亂搞),但是我相信各位開發中的朋友們只要有邏輯,有開頭,只要自己肯動手,都可以自己鉆研出來,舉一反三。畢竟我就是這樣搞出來的,我從來都相信,只要肯學,都會學會,只要肯做,都可以做成。

總結

以上所述是小編給大家介紹的python實現12306搶票及自動郵件發送提醒付款功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

迁西县| 东丽区| 巍山| 长泰县| 蒙山县| 玉溪市| 贵州省| 成武县| 木兰县| 邻水| 漳浦县| 横山县| 陈巴尔虎旗| 正镶白旗| 仁寿县| 汾西县| 西华县| 潞西市| 阿拉善盟| 南昌县| 临澧县| 桂林市| 白银市| 锡林浩特市| 峡江县| 颍上县| 元氏县| 汉阴县| 宁阳县| 陵川县| 股票| 潜江市| 安庆市| 喀什市| 灵川县| 澳门| 涟水县| 舟山市| 彰化市| 澄迈县| 鄂托克前旗|