新版知乎ログインrequestログイン(2)(クラスプログラミング)

13521 ワード

前回、クラスでコードを再構築しましたが、方法は一致していますが、よりきれいに見えます.もう言わないで、コードをつけてください.
#! /usr/local/bin python3.6
"""
@Time    : 2018/4/17 20:00
@Author  : ysj
@Site    : 
@File    : ZhiHuLogIn.py
@Software: PyCharm
"""
import time
import requests
import base64
import json
from hashlib import sha1
import hmac
import os
import uuid
# from PIL import Image
# from multiprocessing import Process
import http.cookiejar as cookielib

#    InsecureRequestWarning  ; verify=True   
# requests.packages.urllib3.disable_warnings()


class ZhiHu:
    """
         ,    ,self.session         requests.session
    """
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0',
               'HOST': 'www.zhihu.com', 'Referer': 'https://www.zhihu.com/signin?next=%2F',
               'Authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20'}

    login_url = 'https://www.zhihu.com/api/v3/oauth/sign_in'
    captcha_url = 'https://www.zhihu.com/api/v3/oauth/captcha?lang=en'
    check_url = 'https://www.zhihu.com/inbox'
    post_data = {
        'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
        'grant_type': 'password',
        'timestamp': str(int(time.time())),
        'source': 'com.zhihu.web',
        'signature': None,
        'username': None,
        'password': None,
        'captcha': None,
        'lang': 'en',
        'ref_source': 'homepage',
        'utm_source': ''
    }
    """
        ,    ,    
    post_data = {
        'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
        'grant_type': 'password',
        'timestamp': '1515398025518',
        'source': 'com.zhihu.web',
        'signature': '30b129980d00e5efb09f16b0334bf4e8601b060b',
        'username': 1,
        'password': 2,
        'captcha': 3,
        'lang': 'en',
        'ref_source': 'homepage',
        'utm_source': ''
    }
    """

    def __init__(self, account, password, cookie_file='zhihu_cookie.txt'):
        self.session = requests.session()
        self.session.headers = self.headers
        self.cookie_file = cookie_file
        self.session.cookies = cookielib.LWPCookieJar(filename=self.cookie_file)
        self.username = account
        self.password = password
        self.check_count = 0
        try:
            self.session.cookies.load(ignore_discard=True, ignore_expires=True)
            print('cookie      ')
        except FileNotFoundError:
            print("cookie      ")
            self.login()
        else:
            if not self.check_login():
                print('cookie    ,      ')
                self.login()
        # self.check_login()

    def login(self):
        """      """
        self.check_count = 0
        self.post_data['username'] = self.username
        self.post_data['password'] = self.password
        self.post_data['captcha'] = self.check_captcha()
        self.post_data['signature'] = self.get_signature()
        self.sign_in()

    def check_login(self):
        """  session  ,           """
        #      ,     200
        res = self.session.get(self.check_url, verify=True, allow_redirects=False)
        code = res.status_code
        if code < 300:
            print('     ')
            return True
        else:
            print('        ')
            return False

    def sign_in(self):
        """    api"""
        response = self.session.post(self.login_url, data=self.post_data, verify=True)
        if self.check_login():
            self.session.cookies.save(ignore_expires=True, ignore_discard=True)
            return True
        else:
            print(response.json())

    def check_captcha(self):
        response = self.session.get(self.captcha_url, verify=True)
        show_captcha = response.json()['show_captcha']
        if not show_captcha:
            return None
        else:
            #     ,         
            response = self.session.put(self.captcha_url, verify=True)
            img = json.loads(response.content)['img_base64']
            img = img.encode('utf-8')
            img_data = base64.b64decode(img)
            filename = str(uuid.uuid4()) + 'tpm.gif'
            with open(filename, 'wb') as f:
                f.write(img_data)
            #          ,       
            # im = Image.open(filename)
            # sub = Process(target=im.show)
            # sub.start()
            # im.show()
            captcha = input('          %s,    :' % filename)
            # sub.terminate()
            # im.close()
            os.remove(filename)
            data = {'input_text': captcha}
            response = self.session.post(self.captcha_url, data=data, verify=True)
            try:
                result = response.json()
            except Exception as ex2:
                print('    post      ,  :{}'.format(ex2))
                """      ,    3        """
                self.check_count += 1
                if self.check_count < 4:
                    self.check_captcha()
            else:
                if result.get('success'):
                    return captcha
                else:
                    print(result)
                    """      ,    3        """
                    self.check_count += 1
                    if self.check_count < 4:
                        self.check_captcha()

    def get_signature(self):
        """      ,        
              ,             signature                  
        """
        def ensure_bytes(value):
            """    ,        """
            return value if isinstance(value, bytes) else value.encode('utf-8')

        hm = hmac.new(b'd1b964811afb40118a12068ff74a12f4', None, sha1)
        try:
            kwargs = self.post_data
            hm.update(ensure_bytes(kwargs['grant_type']))
            hm.update(ensure_bytes(kwargs['client_id']))
            hm.update(ensure_bytes(kwargs['source']))
            hm.update(ensure_bytes(kwargs['timestamp']))
        except KeyError as ex:
            print('    ', ex)
        else:
            return hm.hexdigest()


if __name__ == '__main__':
    login = ZhiHu('18516157608', '*****')
    print(login.session.get(login.check_url, allow_redirects=False).status_code)
    #      302
    print(requests.get('https://www.zhihu.com/inbox', headers=ZhiHu.headers, allow_redirects=False).status_code)