python模擬登錄練習(xí)(一)

上一篇文章模擬登陸存在問題用scrapy無法登錄知乎,后來志明S告訴我是驗證碼的問題,另外知乎上xchaoinfo提到知乎登錄需要保持cookies一致,都不是太理解,暫時找不到解決方案,在查找模擬登錄的方法的時候,發(fā)現(xiàn)了xchaoinfo大神的模擬登錄各大網(wǎng)站的源碼,暫時先去學(xué)習(xí)那個了,scrapy模擬登錄的問題暫時擱置。

先拿相對簡單登錄知乎開始練習(xí)(模仿),以下是根據(jù)xchaoinfo的源碼做的學(xué)習(xí)筆記,知識點在代碼中注釋了,注釋的地方是我看源碼不會的點,然后google查資料后自己的理解(部分注釋是源碼自帶的)。

代碼

import requests
import http.cookiejar
import re
import time
import os.path
from PIL import Image
from lxml import etree


#構(gòu)造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是一個動態(tài)參數(shù)
    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 是二進制內(nèi)容,r.text為unicode內(nèi)容

    # 用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():
    #通過查看用戶個人信息來判斷是否已經(jīng)登錄
    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    #獲得網(wǎng)站的內(nèi)容
        print(login_page.status_code)   #測試是否登錄成功
        print(login_code)   #打印網(wǎng)站的內(nèi)容
    except:
        post_data['captcha'] = get_captcha()
        login_page = session.post(post_url,data=post_data,headers=headers)
        login_code = eval(login_page.text) #eval函數(shù)可以把list,tuple,dict和string相互轉(zhuǎn)化
        print(login_code['msg'])
    session.cookies.save() #保存cookies,后續(xù)爬取內(nèi)容時需要


try:
    input = raw_input
except:
    pass

if __name__ == '__main__':
    if islogin():
        print('您已經(jīng)登錄')
    else:
        account = input('請輸入你的用戶名\n>  ')
        secret = input("請輸入你的密碼\n>  ")
        login(account,secret)

本次練習(xí)學(xué)到的知識點
1.簡單學(xué)習(xí)了requests庫,了解requests簡單get和post方法
2.了解requests庫的session類,
session.cookies = http.cookiejar.LWPCookieJar(filename='cookies')能夠講cookies保存到本地。
同時session能夠使用同一個cookies訪問不同的url,為全站爬去提供簡單的解決方案。
3.知道了網(wǎng)站的重定向是什么,學(xué)了這么久的爬蟲,居然不知道重定向,汗。
4.因為對re模塊不是太熟悉,先學(xué)了lxml模塊的xpath,因為scrapy用xpath習(xí)慣了,源碼好多用re的地方改成了xpath解析。
5.安裝了pillow庫,雖然完全不知道pillow庫強大的功能。
6.好吧,已經(jīng)學(xué)到蠻多了,最重要的是通過這次練習(xí)感覺直接對著源碼,一句一句的理解(慢慢測試),要比直接找現(xiàn)成的解決方法更有用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容