python爬蟲-知乎登錄


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Required
- requests (必須)
- pillow (可選)
'''

import requests
try:
    import cookielib
except:
    import http.cookiejar as cookielib
import re
import time
import os.path
try:
    from PIL import Image
except:
    pass
#使用驗證碼識別庫
#import pytesseract


# 構造 Request headers
agent = 'Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0'
headers = {
    'User-Agent': agent
}

# 使用登錄cookie信息
session = requests.session()
session.cookies = cookielib.LWPCookieJar(filename='cookies')
try:
    session.cookies.load(ignore_discard=True)
except:
    print("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')
        #使用驗證碼識別,系統需要安裝tesseract-ocr軟件
        #下載地址:https://jaist.dl.sourceforge.net/project/tesseract-ocr-alt/tesseract-ocr-setup-3.02.02.exe
        #由於驗證碼識別,測試識別率不高,因此暫時不使用,尋找更好的識別方法再加
        #code = pytesseract.image_to_string(im)
        #print(code)
        im.show()
        im.close()
        #if len(code)!=4:
        #    print('自動識別不出驗證碼,請手動輸入驗證碼!')
        #else:
        #    captcha = code
        #    return captchac
    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,allow_redirects=False).status_code
    if int(x=login_code) == 200:
        return True
    else:
        return False



def login(secret, account):
    # 通過輸入的用戶名判斷是否是手機號
    if re.match(r"^1\d{10}$", account):
        print("手機號登錄 \n")
        post_url = 'https://www.zhihu.com/login/phone_num'
        postdata = {
            '_xsrf': get_xsrf(),
            'password': secret,
            'remember_me': 'true',
            'phone_num': account,
        }
    #可加上郵箱的判斷,這里不加了
    else:
        print("郵箱登錄 \n")
        post_url = 'https://www.zhihu.com/login/email'
        postdata = {
            '_xsrf': get_xsrf(),
            'password': secret,
            'remember_me': 'true',
            'email': account,
        }
    try:
        # 不需要驗證碼直接登錄成功
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = login_page.text
        print(login_page.status)
        print(login_code)
    except:
        # 需要輸入驗證碼后才能登錄成功
        postdata["captcha"] = get_captcha()
        login_page = session.post(post_url, data=postdata, headers=headers)
        login_code = eval(login_page.text)
        print(login_code['msg'])
        return login_code['r']
    session.cookies.save()

try:
    input = raw_input
except:
    pass


if __name__ == '__main__':
    while True:
        if isLogin():
            print('您已經登錄')
        else:
            account = input('請輸入你的用戶名\n>  ')
            secret = input("請輸入你的密碼\n>  ")
            result = login(secret, account)
            if result == 0:
                #爬取登錄成功后的網站內容
                conf_url = "https://www.zhihu.com/settings/profile"
                text = session.get(conf_url,headers=headers).text
                print(text)
                break

以上代碼在python 2.*中運行時,只需修改代碼的print處即可

代碼部分參考網友,代碼持續更新優化中,如有錯誤或更優的方法歡迎大家的留言!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM