上一篇文章模擬登陸存在問(wèn)題用scrapy無(wú)法登錄知乎动壤,后來(lái)志明S告訴我是驗(yàn)證碼的問(wèn)題这嚣,另外知乎上xchaoinfo提到知乎登錄需要保持cookies一致辙售,都不是太理解肛鹏,暫時(shí)找不到解決方案,在查找模擬登錄的方法的時(shí)候脂矫,發(fā)現(xiàn)了xchaoinfo大神的模擬登錄各大網(wǎng)站的源碼,暫時(shí)先去學(xué)習(xí)那個(gè)了霉晕,scrapy模擬登錄的問(wèn)題暫時(shí)擱置庭再。
先拿相對(duì)簡(jiǎn)單登錄知乎開始練習(xí)(模仿),以下是根據(jù)xchaoinfo的源碼做的學(xué)習(xí)筆記牺堰,知識(shí)點(diǎn)在代碼中注釋了拄轻,注釋的地方是我看源碼不會(huì)的點(diǎn),然后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() #實(shí)例化一個(gè)session類恨搓,session能夠用同一個(gè)cookies訪問(wèn)不同的url
session.cookies = http.cookiejar.LWPCookieJar(filename='cookies')
try:
session.cookies.load(ignore_discard=True)
except:
print('cookie未加載')
def get_xsrf():
#_xrsf是一個(gè)動(dòng)態(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庫(kù)解析
_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" #獲得驗(yàn)證碼圖片的地址,t是需要用到格林威治時(shí)間戳
print(captcha_url)
r = session.get(captcha_url,headers=headers)
with open('captcha.jpg','wb') as f:
f.write(r.content) #r.content 是二進(jìn)制內(nèi)容,r.text為unicode內(nèi)容
# 用pillow 的 Image 顯示驗(yàn)證碼
# 如果沒有安裝 pillow 到源代碼所在的目錄去找到驗(yàn)證碼然后手動(dòng)輸入
try:
im = Image.open('captcha.jpg')
im.show()
im.close()
except:
print(r'請(qǐng)到 %s 目錄找到captcha.jpg 手動(dòng)輸入' % os.path.abspath('captcha.jpg'))
captcha = input('請(qǐng)輸入驗(yàn)證碼:\n')
return captcha
def islogin():
#通過(guò)查看用戶個(gè)人信息來(lái)判斷是否已經(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):
#通過(guò)輸入的用戶名判斷是否是手機(jī)號(hào)
if re.match(r'^1\d{10}$',account):
print("手機(jī)號(hào)登錄 \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("您輸入的賬號(hào)有問(wèn)題斧抱,請(qǐng)重新輸入")
return 0 #這里的return起的作用是跳出去本次登錄
post_url = 'https://www.zhihu.com/login/email'
post_data = {
'_xsrf': get_xsrf(),
'password': secret,
'remember_me': 'true',
'email': account,
}
try:
# 不需要驗(yàn)證碼直接登錄成功
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) #測(cè)試是否登錄成功
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)容時(shí)需要
try:
input = raw_input
except:
pass
if __name__ == '__main__':
if islogin():
print('您已經(jīng)登錄')
else:
account = input('請(qǐng)輸入你的用戶名\n> ')
secret = input("請(qǐng)輸入你的密碼\n> ")
login(account,secret)
本次練習(xí)學(xué)到的知識(shí)點(diǎn)
1.簡(jiǎn)單學(xué)習(xí)了requests庫(kù)常拓,了解requests簡(jiǎn)單get和post方法
2.了解requests庫(kù)的session類,
session.cookies = http.cookiejar.LWPCookieJar(filename='cookies')能夠講cookies保存到本地辉浦。
同時(shí)session能夠使用同一個(gè)cookies訪問(wèn)不同的url弄抬,為全站爬去提供簡(jiǎn)單的解決方案。
3.知道了網(wǎng)站的重定向是什么宪郊,學(xué)了這么久的爬蟲掂恕,居然不知道重定向,汗弛槐。
4.因?yàn)閷?duì)re模塊不是太熟悉懊亡,先學(xué)了lxml模塊的xpath,因?yàn)閟crapy用xpath習(xí)慣了乎串,源碼好多用re的地方改成了xpath解析店枣。
5.安裝了pillow庫(kù),雖然完全不知道pillow庫(kù)強(qiáng)大的功能灌闺。
6.好吧艰争,已經(jīng)學(xué)到蠻多了,最重要的是通過(guò)這次練習(xí)感覺直接對(duì)著源碼桂对,一句一句的理解(慢慢測(cè)試)甩卓,要比直接找現(xiàn)成的解決方法更有用。