当前位置:博客首页>>Python >> 阅读正文

Python模拟百度登录

作者: 郑晓 分类: Python 发布于: 2015-07-09 21:43 浏览(10,938) 评论(2)


本来写这个玩意儿是想用来自动登录百度,然后根据贴吧内的的排名抓取会员头像的,比如生成一个贴吧千人头像图或万人头像图。也算是练练手。
完成后才发现抓那个贴吧排名完全不需要登录…也好,以后用来做自动一键签到(经常忘打卡),抢二楼什么的,也不错~~

如今在博客上发个文章用不了多长时间就被抄走了,感觉自己能做的也只有在此鄙视一下它们。
废话太多,容易招人恨,以下是代码:

#-*- 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!

↓↓微信扫码请我吃份正宗的烤面筋,可带劲啦↓↓
       

本文采用知识共享署名-非商业性使用 3.0 中国大陆许可协议进行许可,转载时请注明出处及相应链接。

本文永久链接: https://www.zh30.com/python-baidu-login.html

Python模拟百度登录:目前有2 条留言

用户评论头像 harries发表于 2016年01月05日 17:06[回复]

python用的好熟呀

用户评论头像 发表于 2015年07月14日 17:27[回复]

学习了