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

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

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

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

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)

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

f.write(response.content)

f.close()

self.check_code()

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

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

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

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

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

而這時我們就有了思路,先用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保存到本地,以備下一次使用。

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

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


分享到:


相關文章: