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)
f = open('code.jpg','wb')
f.write(response.content)
f.close()
self.check_code()
不知道大家對那一張驗證碼有沒有印象,說起網上購票,很多人談起12306首先想到的就是他的驗證碼。登錄的時候各種奇葩驗證碼,什麼選擇其中的龍舟,茶几往往自己不是搶不到票,而是被驗證碼擋在了門外。而對於爬蟲來說更是如此,12306的首個關卡就是登錄的時候驗證碼。12306的驗證碼有時連人類識別起來都非常困難,就別說咱們的程序了。所以,很多人爬取12306 的時候就是被驗證碼攔住了,久久不能前行。而今天,我將和大家分享一下12306的登錄問題和咱們關心的車次信息查詢問題。
首先打開12306的登錄頁面,F12打開管理者工具,我們故意輸錯驗證碼,發現出現了兩條ajax請求,我們發現其中一條返回的結果是一張圖片,這張圖片恰好是我們的驗證碼。而另一條信息則是我們選擇錯誤驗證碼返回的信息。
而這時我們就有了思路,先用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保存到本地,以備下一次使用。
閱讀更多 繁華落盡and曲終人散 的文章