美文网首页
python模拟登录练习(一)

python模拟登录练习(一)

作者: xcaojianhong | 来源:发表于2017-02-18 21:02 被阅读139次

    上一篇文章模拟登陆存在问题用scrapy无法登录知乎,后来志明S告诉我是验证码的问题,另外知乎上xchaoinfo提到知乎登录需要保持cookies一致,都不是太理解,暂时找不到解决方案,在查找模拟登录的方法的时候,发现了xchaoinfo大神的模拟登录各大网站的源码,暂时先去学习那个了,scrapy模拟登录的问题暂时搁置。

    先拿相对简单登录知乎开始练习(模仿),以下是根据xchaoinfo的源码做的学习笔记,知识点在代码中注释了,注释的地方是我看源码不会的点,然后google查资料后自己的理解(部分注释是源码自带的)。

    代码

    import requests
    import http.cookiejar
    import re
    import time
    import os.path
    from PIL import Image
    from lxml import etree
    
    
    #构造headers
    user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
    
    headers = {'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Encoding':'gzip, deflate, sdch, br',
                'Accept-Language':'zh-CN,zh;q=0.8',
                'Cache-Control':'max-age=0',
                'Connection':'keep-alive',
                'Host':'www.zhihu.com',
                'Upgrade-Insecure-Requests':'1',
                'User-Agent':user_agent,
                }
    
    
    #使用登录cookies信息
    session = requests.session()    #实例化一个session类,session能够用同一个cookies访问不同的url
    session.cookies = http.cookiejar.LWPCookieJar(filename='cookies')
    try:
        session.cookies.load(ignore_discard=True)
    except:
        print('cookie未加载')
    
    
    def get_xsrf():
        #_xrsf是一个动态参数
        start_url = 'https://www.zhihu.com/#signin'
        start_response = session.get(start_url,headers=headers)
        html = start_response.text
        #print(html)
        select = etree.HTML(html)   #使用lxml库解析
        _xsrf = select.xpath('//html/body/input[@name="_xsrf"]/@value')[0]
        return _xsrf
    
    def get_captcha():
        t = str(int(time.time()*1000))
        captcha_url =  'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"   #获得验证码图片的地址,t是需要用到格林威治时间戳
        print(captcha_url)
        r = session.get(captcha_url,headers=headers)
        with open('captcha.jpg','wb') as f:
            f.write(r.content)  #r.content 是二进制内容,r.text为unicode内容
    
        # 用pillow 的 Image 显示验证码
        # 如果没有安装 pillow 到源代码所在的目录去找到验证码然后手动输入
    
        try:
            im = Image.open('captcha.jpg')
            im.show()
            im.close()
        except:
             print(r'请到 %s 目录找到captcha.jpg 手动输入' % os.path.abspath('captcha.jpg'))
        captcha = input('请输入验证码:\n')
        return captcha
    
    def islogin():
        #通过查看用户个人信息来判断是否已经登录
        url = 'https://www.zhihu.com/settings/profile'
        login_code = session.get(url,headers=headers,allow_redirects=False).status_code   #不允许重定向
        if login_code == 200:
            return True
        else:
            return  False
    
    def login(account,secret):
        #通过输入的用户名判断是否是手机号
        if re.match(r'^1\d{10}$',account):
            print("手机号登录 \n")
            post_url = 'https://www.zhihu.com/login/phone_num'
            post_data = {
                '_xsrf': get_xsrf(),
                'password': secret,
                'remember_me': 'true',
                'phone_num': account,
            }
        else:
            if '@' in account:
                print("邮箱登录 \n")
            else:
                print("您输入的账号有问题,请重新输入")
                return 0    #这里的return起的作用是跳出去本次登录
            post_url = 'https://www.zhihu.com/login/email'
            post_data = {
                '_xsrf': get_xsrf(),
                'password': secret,
                'remember_me': 'true',
                'email': account,
            }
        try:
            # 不需要验证码直接登录成功
            login_page = session.post(post_url,data=post_data,headers=headers)
            login_code = login_page.text    #获得网站的内容
            print(login_page.status_code)   #测试是否登录成功
            print(login_code)   #打印网站的内容
        except:
            post_data['captcha'] = get_captcha()
            login_page = session.post(post_url,data=post_data,headers=headers)
            login_code = eval(login_page.text) #eval函数可以把list,tuple,dict和string相互转化
            print(login_code['msg'])
        session.cookies.save() #保存cookies,后续爬取内容时需要
    
    
    try:
        input = raw_input
    except:
        pass
    
    if __name__ == '__main__':
        if islogin():
            print('您已经登录')
        else:
            account = input('请输入你的用户名\n>  ')
            secret = input("请输入你的密码\n>  ")
            login(account,secret)
    

    本次练习学到的知识点
    1.简单学习了requests库,了解requests简单get和post方法
    2.了解requests库的session类,
    session.cookies = http.cookiejar.LWPCookieJar(filename='cookies')能够讲cookies保存到本地。
    同时session能够使用同一个cookies访问不同的url,为全站爬去提供简单的解决方案。
    3.知道了网站的重定向是什么,学了这么久的爬虫,居然不知道重定向,汗。
    4.因为对re模块不是太熟悉,先学了lxml模块的xpath,因为scrapy用xpath习惯了,源码好多用re的地方改成了xpath解析。
    5.安装了pillow库,虽然完全不知道pillow库强大的功能。
    6.好吧,已经学到蛮多了,最重要的是通过这次练习感觉直接对着源码,一句一句的理解(慢慢测试),要比直接找现成的解决方法更有用。

    相关文章

      网友评论

          本文标题:python模拟登录练习(一)

          本文链接:https://www.haomeiwen.com/subject/ogddwttx.html