1. 程式人生 > >Python模擬百度登入

Python模擬百度登入

注:本文轉載,如有侵權,請告知將予以刪除

原文章連結:https://www.zh30.com/python-baidu-login.html

 

 

 

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

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

#-*- coding:gbk -*-
#
# 模擬百度登入 for Python2.7
# 其中顯示驗證碼部分 需要使用PIL庫
# 需要驗證碼時,會建立一個Tkinter視窗,用於顯示和輸入驗證碼,回車後窗口關閉。
# author:zx(www.zh30.com)
#
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檔案並驗證有效性
try:
    cookie.load(ignore_discard=True, ignore_expires=True)
    print '讀取登入狀態的cookie成功'
    #do something...
    
except Exception:
    #cookie不存在或無效時 開始進行模擬登入並重新生成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是否需要驗證碼
    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:
        #需要驗證碼 建立一個tk顯示驗證碼 並提示使用者輸入
        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='您的帳號異常,需要輸入驗證碼')
        label1.pack()

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

        label3 = tk.Label(tk_root, text='輸入驗證碼並按回車確認')
        label3.pack()
        entry = tk.Entry(tk_root)
        entry.bind('<Key>', presskey)
        entry.pack()
        tk_root.mainloop()

    #構造登入表單
    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()
    #驗證登入結果
    
    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 '登入失敗:密碼錯誤'
    elif errno == '257':
        print '登入失敗:驗證碼錯誤'
    else:
        print '登入失敗'
        print result #失敗後 列印返回字元 by zh30.com

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