知乎模擬登陸 requests session

Python 3.5html

# -*- coding: utf-8 -*-
"""
Created on Wed May  3 16:26:55 2017

@author: x-power
"""

import requests
import http.cookiejar as cookielib
import re
import time
import os.path
from PIL import Image



# 構造 Request headers
headers = {
    "Host": "www.zhihu.com",
    "Referer": "https://www.zhihu.com/",
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0',
}



# 構造 cookie 信息
session = requests.session()
session.cookies = cookielib.LWPCookieJar(filename='cookies')
try:
    session.cookies.load(ignore_discard=True) # 若是已經有 cookie信息的話 直接用於登陸
except:
    print("Cookie 未能加載")

# 之後再用session 訪問的時候 都帶着 本地已經固定的cookie信息,表明都是一臺機器發出的請求。


def get_xsrf():
    '''_xsrf 是一個動態變化的參數'''
    index_url = 'https://www.zhihu.com'
    # 獲取登陸時須要用到的_xsrf
    index_page = session.get(index_url, headers=headers) 
    html = index_page.text
    pattern = r'name="_xsrf" value="(.*?)"'
    # 這裏的_xsrf 返回的是一個list
    _xsrf = re.findall(pattern, html)
    return _xsrf[0]


# 獲取驗證碼
def get_captcha():
    t = str(int(time.time() * 1000))
    captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
    r = session.get(captcha_url, headers=headers)
    with open('captcha.jpg', 'wb') as f:
        f.write(r.content)
        f.close()
    # 用pillow 的 Image 顯示驗證碼
    # 若是沒有安裝 pillow 到源代碼所在的目錄去找到驗證碼而後手動輸入
    try:
        im = Image.open('captcha.jpg')
        im.show()
        im.close()
    except:
        print(u'請到 %s 目錄找到captcha.jpg 手動輸入' % os.path.abspath('captcha.jpg'))
    captcha = input("please input the captcha\n>")
    return captcha


def isLogin():
    # 經過查看用戶我的信息來判斷是否已經登陸
    url = "https://www.zhihu.com/settings/profile"
    login_code = session.get(url, headers=headers, allow_redirects=False).status_code  #allow_redirects 不容許重定向
    if login_code == 200:
        return True
    else:
        return False


def login(secret, account):
    _xsrf = get_xsrf()
    headers["X-Xsrftoken"] = _xsrf
    headers["X-Requested-With"] = "XMLHttpRequest"
    # 經過輸入的用戶名判斷是不是手機號
    if re.match(r"^1\d{10}$", account):
        print("手機號登陸 \n")
        post_url = 'https://www.zhihu.com/login/phone_num'
        postdata = {
            '_xsrf': _xsrf,
            'password': secret,
            'phone_num': account
        }
    else:
        if "@" in account:
            print("郵箱登陸 \n")
        else:
            print("你的帳號輸入有問題,請從新登陸")
            return 0
        post_url = 'https://www.zhihu.com/login/email'
        postdata = {
            '_xsrf': _xsrf,
            'password': secret,
            'email': account
        }
    # 不須要驗證碼直接登陸成功
    login_page = session.post(post_url, data=postdata, headers=headers)
    login_code = login_page.json()
    if login_code['r'] == 1:
        # 不輸入驗證碼登陸失敗
        # 使用須要輸入驗證碼的方式登陸
        postdata["captcha"] = get_captcha()
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = login_page.json()
        print(login_code['msg'])
    # 保存 cookies 到文件,
    # 下次能夠使用 cookie 直接登陸,不須要輸入帳號和密碼
    session.cookies.save()




if __name__ == '__main__':
    if isLogin():
        print('您已經登陸')
    else:
        account = input('請輸入你的用戶名\n>  ')
        secret = input("請輸入你的密碼\n>  ")
login(secret, account)
相關文章
相關標籤/搜索