1. 程式人生 > >12306聽說是全國最難爬的網站?Python照樣攻破爬取12306車票資訊

12306聽說是全國最難爬的網站?Python照樣攻破爬取12306車票資訊

2018年年初,我對自己說:“你的人生在未來的幾個月內可能會有一次大的變故,你一定要拼盡全力,因為你和別人的生活不一樣。你沒有任何退路。”

各位同學們好,隨著幾個月的python學習,漸漸的被這門語言的魅力所折服。其中也學到了許多有意思的東西,所以想把個人認為好玩的和大家分享一下。廢話不多說,直接上程式碼:

class Login():

"""實現12306的登入"""

def __init__(self):

self.capycha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.27575294592849064'

self.capycha_check_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'

self.login_url = 'https://kyfw.12306.cn/passport/web/login'

def download_code(self):

"""1.下載驗證碼"""

response session.get(self.capycha_url)

open('code.jpg','wb')

f.write(response.content)

f.close()

self.check_code()

不知道大家對那一張驗證碼有沒有印象,說起網上購票,很多人談起12306首先想到的就是他的驗證碼。登入的時候各種奇葩驗證碼,什麼選擇其中的龍舟,茶几往往自己不是搶不到票,而是被驗證碼擋在了門外。而對於爬蟲來說更是如此,12306的首個關卡就是登入的時候驗證碼。12306的驗證碼有時連人類識別起來都非常困難,就別說咱們的程式了。所以,很多人爬取12306 的時候就是被驗證碼攔住了,久久不能前行。而今天,我將和大家分享一下12306的登入問題和咱們關心的車次資訊查詢問題。

首先開啟12306的登入頁面,F12開啟管理者工具,我們故意輸錯驗證碼,發現出現了兩條ajax請求,我們發現其中一條返回的結果是一張圖片,這張圖片恰好是我們的驗證碼。而另一條資訊則是我們選擇錯誤驗證碼返回的資訊。

小編給大家推薦一個學習氛圍超好的地方,python交流企鵝裙:【611+530+101】適合在校大學生,小白,想轉行,想通過這個找工作的加入。裙裡有大量學習資料,有大神解答交流問題,每晚都有免費的直播課程

而這時我們就有了思路,先用get請求吧驗證碼圖片下載到本地,然後把我們的識別情況以post方式傳送,我們可以發現關鍵的點事answer這個引數,這個就是我們的驗證碼的選擇情況。不知道大家看見這些數字想到的是什麼了沒有。沒錯,就是座標系驗證碼。每一張圖片都是一片固定位置,我們用滑鼠點一下返回給伺服器的都是一個座標。這時,有了思路。就開始講程式碼:我先定義了一個Login類,用來實現登入,我首先通過requests請求下載驗證碼圖片,然後下載到本地,識別之後將資料以post方式返回給伺服器。

def check_code(self):

"""2.檢測驗證碼"""

code input("請輸入驗證碼:") #要去掉驗證碼頭部30px左右

data = {

'answer': code.split(),

'login_site': 'E',

'rand': 'sjrand',

}

res session.post(self.capycha_check_url,data=data)

res_json res.json()

if res_json['result_code'] != '4':

print("驗證碼錯誤")

self.download_code()

else:

self.login()

這中間有一個問題,就是如何告訴伺服器我識別的這個驗證碼就是剛才我下載的那張?那這裡又用到了一個知識點,就是 session的處理。簡單點說就是會話保持。不過這個學過web開發的一般都會有印象,常常用來保持登入狀態。

def login(self):

"""3.登入"""

login_data = {

'username': config.username,

'password': config.password,

'appid': 'otn',

}

result session.post(self.login_url,data=login_data)

print(result.text)

with open('cookies.json','w') as f:

json.dump(session.cookies.get_dict(),f)

那麼接下來就是傳送使用者名稱和密碼實現登入了。登入完成之後我們就可以把cookies儲存到本地,以備下一次使用。