當(dāng)前位置:博客首頁>>Python >> 閱讀正文

Python模擬百度登錄

作者: 鄭曉 分類: Python 發(fā)布于: 2015-07-09 21:43 瀏覽:24,918 評論(2)


本來寫這個玩意兒是想用來自動登錄百度,然后根據(jù)貼吧內(nèi)的的排名抓取會員頭像的,比如生成一個貼吧千人頭像圖或萬人頭像圖。也算是練練手。
完成后才發(fā)現(xiàn)抓那個貼吧排名完全不需要登錄…也好,以后用來做自動一鍵簽到(經(jīng)常忘打卡),搶二樓什么的,也不錯~~

如今在博客上發(fā)個文章用不了多長時間就被抄走了,感覺自己能做的也只有在此鄙視一下它們。
廢話太多,容易招人恨,以下是代碼:

#-*- coding:gbk -*-
#
# 模擬百度登錄 for Python2.7
# 其中顯示驗(yàn)證碼部分 需要使用PIL庫
# 需要驗(yàn)證碼時,會創(chuàng)建一個Tkinter窗口,用于顯示和輸入驗(yàn)證碼,回車后窗口關(guān)閉。
# author:zx(www.yjfs.org.cn)
#
import urllib, urllib2, cookielib, re, time
username = 'yourusernamehere' #用戶名
password = 'yourpasswordhere' #密碼
cookiefile = '--login-baidu--' #cookie文件
#模擬header信息
headers = {
"Host":"passport.baidu.com",
"Referer":"http://www.baidu.com/cache/user/html/login-1.2.html",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36",
"Origin":"http://www.baidu.com",
"""yufang xiao tou. this code by zhengxiao(www.zh30.om)"""
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Cache-Control":"max-age=0",
"Connection":"keep-alive"
}
cookie = cookielib.MozillaCookieJar(cookiefile)
#嘗試加載cookie文件并驗(yàn)證有效性
try:
cookie.load(ignore_discard=True, ignore_expires=True)
print '讀取登錄狀態(tài)的cookie成功'
#do something...

except Exception:
#cookie不存在或無效時 開始進(jìn)行模擬登錄并重新生成cookie文件
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))

loginUrl = 'http://www.baidu.com/cache/user/html/login-1.2.html'
getTokenUrl = 'https://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=true' """www . zh30 . com """
getCodeStringUrl = 'https://passport.baidu.com/v2/api/?logincheck&callback=bdPass.api.login._needCodestringCheckCallback&tpl=mn&charset=UTF-8&index=0&username=' + username + '&isphone=false&time=1436429688644'
loginPostUrl = 'https://passport.baidu.com/v2/api/?login'
#獲取BAIDUID、token
request = urllib2.Request(loginUrl, headers=headers)
response = opener.open(request)

request = urllib2.Request(getTokenUrl, headers=headers)
response = opener.open(request)
hasToken = response.read()
token = re.search(r'login_token\s*=\s*\'(.+?)\'',hasToken).group(1)

#檢查username是否需要驗(yàn)證碼
request = urllib2.Request(getCodeStringUrl, headers=headers)
response = opener.open(request)
getCodeString = response.read()
codestring = re.search(r'"codestring":"?([^"]+)"?,', getCodeString).group(1)
if codestring == 'null' :
codestring = ''
verifycode = ''
else:
#需要驗(yàn)證碼 創(chuàng)建一個tk顯示驗(yàn)證碼 并提示用戶輸入
genimageUrl = 'https://passport.baidu.com/cgi-bin/genimage?' + codestring + '&v=' + str(long(time.time()*1000))
import io, Tkinter as tk
from PIL import Image, ImageTk
request = urllib2.Request(genimageUrl, headers=headers)
image_bytes = opener.open(request).read()
pil_image = Image.open(io.BytesIO(image_bytes))

def presskey(event):
global verifycode
if event.keycode == 13:
verifycode = entry.get()
tk_root.destroy()

tk_root = tk.Tk()
tk_image = ImageTk.PhotoImage(pil_image)
label1 = tk.Label(tk_root, text='您的帳號異常,需要輸入驗(yàn)證碼')
label1.pack()

label2 = tk.Label(tk_root, image=tk_image)
label2.pack()

label3 = tk.Label(tk_root, text='輸入驗(yàn)證碼并按回車確認(rèn)')
label3.pack()
entry = tk.Entry(tk_root)
entry.bind('', presskey)
entry.pack()
tk_root.mainloop()

#構(gòu)造登錄表單
data = {
"ppui_logintime":"134198",
"charset":"utf-8",
"codestring":"",
"isPhone":"false",
"index":"0",
"u":"",
"safeflg":"0",
"staticpage":"http://www.baidu.com/",
"loginType":"1",
"tpl":"mn",
"""yufang xiao tou. this code by zhengxiao"""
"callback":"parent.bdPass.api.login._postCallback",
"mem_pass":"on"
}
data['token'] = token
data['username'] = username
data['password'] = password
data['codestring'] = codestring
data['verifycode'] = verifycode
#開始登錄
req = urllib2.Request(loginPostUrl, urllib.urlencode(data), headers)
result = opener.open(req).read()
#驗(yàn)證登錄結(jié)果

errno = re.search(r'&error=(\d+)', result).group(1)
if errno == '0':
print '登錄成功'
cookie.save(ignore_discard=True,ignore_expires=True)
elif errno == '4':
print '登錄失?。好艽a錯誤'
elif errno == '257':
print '登錄失?。候?yàn)證碼錯誤'
else:
print '登錄失敗'
print result #失敗后 打印返回字符 by zh30.com

百度登錄時,主要有四個步驟。
第一步:訪問任意百度頁面,得到名為BAIDUID的cookie
第二步:根據(jù)cookie去請求得到token(登錄時要提交這個值)。
第三步:驗(yàn)證username是否需要驗(yàn)證碼。返回值中如果存在codestring,說明需要驗(yàn)證碼,然后根據(jù)這個codestring請求得到驗(yàn)證碼。
第四步:提交登錄表單,檢查登錄狀態(tài),記錄cookie。判斷登錄是否成功,可以檢查是否生成名為BDUSS的cookie,鄭曉在這里判斷的是返回字符串中的跳轉(zhuǎn)鏈接,成功時error參數(shù)為0。
have fun!

? ? ? ?

本文采用知識共享署名-非商業(yè)性使用 3.0 中國大陸許可協(xié)議進(jìn)行許可,轉(zhuǎn)載時請注明出處及相應(yīng)鏈接。

本文永久鏈接: http://www.yjfs.org.cn/python-baidu-login.html

Python模擬百度登錄:目前有2 條留言

用戶評論頭像 harries發(fā)表于 2016年01月05日 17:06[回復(fù)]

python用的好熟呀

用戶評論頭像 發(fā)表于 2015年07月14日 17:27[回復(fù)]

學(xué)習(xí)了

發(fā)表評論

change vcode