鍍金池/ 問(wèn)答/Python  C/ 豆瓣模擬登陸保存Cookie后下次直接登陸失敗

豆瓣模擬登陸保存Cookie后下次直接登陸失敗

問(wèn)題描述

一個(gè)模擬登陸豆瓣的python小程序,對(duì)于正常輸入用戶名和密碼進(jìn)行登陸正常,但是當(dāng)我第一次登陸成功后將cookie保存下來(lái)下次使用cookie而不用用戶名和密碼再登陸時(shí),卻無(wú)法正常登陸。以下我將cookie的保存和讀取單獨(dú)寫(xiě)出來(lái)我的實(shí)現(xiàn)過(guò)程:

# 登陸成功的cookie保存
with open('cookie', 'wb') as f:
        pickle.dump(Session.cookies,f)
# 登陸前檢查是否有cookie并嘗試讀取
Session=requests.session()
# 讀取是否保存有cookie
try:
    with open('cookie','rb') as f:
        Session.cookies=pickle.load(f)
        #這里我講讀到的cookie輸出
        print(Session.cookies)
# 如果沒(méi)有cookie,就讀入用戶輸入
except:
    data['form_email']=input('Please input your account:')
    data['form_password']=input('Please input your password:')

對(duì)于讀取cookie的方式,我的程序顯示的確讀到了之前保存的cookie:
對(duì)于程序中的print(Session.cookies)輸出如下:

<RequestsCookieJar[<Cookie as="https://www.douban.com/" for .douban.com/>, <Cookie bid=Lx54kqS0AA4 for .douban.com/>, <Cookie ck=GB1e for .douban.com/>, <Cookie dbcl2="152654498:lA0IPNlgLNQ" for .douban.com/>]>

進(jìn)行登陸的語(yǔ)句如下:

page_login=Session.post(url,data=data,headers=headers)

但是此時(shí)我將page_login的信息全部輸入時(shí)我發(fā)現(xiàn)頁(yè)面源代碼顯示賬號(hào)不能為空,即登陸失敗。也就是說(shuō)好像豆瓣沒(méi)有管我的cookie?

疑問(wèn)

回答者應(yīng)當(dāng)對(duì)如下疑問(wèn)(不僅限于)進(jìn)行解釋或說(shuō)明:
1.為什么此時(shí)的cookie沒(méi)有讓我直接登入豆瓣網(wǎng)頁(yè)?
2.應(yīng)該如何解決這個(gè)問(wèn)題?即如何使用上次的cookie進(jìn)行成功登陸?如果可以請(qǐng)給出修改的代碼或可行建議。

程序代碼

由于我的描述可能有不足之處,如有覺(jué)得我描述的不夠充分的地方可以參考我的代碼(已加入注釋)

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
from os import remove
from PIL import Image
import pickle
#import http.cookiejar as cookielib
url='https://www.douban.com/login'
data={'source':None,
      'remember':'on'
    }

headers = {'Host':'www.douban.com',
           'Referer': 'https://www.douban.com/',
           'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
           'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
           'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
           'Accept-Encoding':'gzip, deflate, br'}

Session=requests.session()
# 讀取是否保存有cookie
try:
    with open('cookie','rb') as f:
        Session.cookies=pickle.load(f)
        #這里我將讀到的cookie輸出
        print(Session.cookies)
# 如果沒(méi)有cookie,就讀入用戶輸入
except:
    data['form_email']=input('Please input your account:')
    data['form_password']=input('Please input your password:')

# 獲得登陸界面的驗(yàn)證碼
def get_captcha():
    req=requests.post(url,data=data)
    page_bf=BeautifulSoup(req.text,'html.parser')
    # 尋找驗(yàn)證碼的圖片(有可能不需要驗(yàn)證碼 這時(shí)返回NULL)
    try:
        img_src=page_bf.find('img',id='captcha_image').get('src')
    except:
        return 'NULL','NULL'
    # 如果需要驗(yàn)證碼下載該驗(yàn)證碼并打開(kāi)
    img=requests.get(img_src)
    if img.status_code==200:
        with open('captcha.jpg','wb') as f:
            f.write(img.content)
    image=Image.open('captcha.jpg')
    image.show()
    # 讓用戶根據(jù)驗(yàn)證碼圖片輸入驗(yàn)證碼
    captcha=input('please input the captcha:')
    remove('captcha.jpg')
    # 由于post-data里還要求captcha-id所以我從圖片網(wǎng)址中截取id
    captcha_id=img_src[img_src.find('=')+1:]
    captcha_id=captcha_id[:captcha_id.find('&')]
    return captcha,captcha_id

def login():
    #獲得驗(yàn)證碼和驗(yàn)證碼id
    captcha,captcha_id=get_captcha()
    if captcha!='NULL':
        data['captcha-solution']=captcha
        data['captcha-id']=captcha_id
    # 進(jìn)行登陸
    page_login=Session.post(url,data=data,headers=headers)
    # 為了驗(yàn)證是否登陸成功我將登陸返回的頁(yè)面html打印出來(lái)發(fā)現(xiàn)登陸失敗
    #print(page_login.text)
    page_login_bf=BeautifulSoup(page_login.text,'html.parser')
    # 如果登陸成功就可以找到熱點(diǎn)新聞并打印
    hot_topic=page_login_bf.find_all('a',class_='rec_topics_name')
    for i,topic in enumerate(hot_topic):
        print('%d.%s'%(i+1,topic.string))
    # 將此時(shí)的cookie保存方便下次登陸
    with open('cookie', 'wb') as f:
        pickle.dump(Session.cookies,f)

if __name__=='__main__':
    login()
ps 本人初學(xué)爬蟲(chóng)知識(shí),如有錯(cuò)誤懇請(qǐng)指出,十分感謝
回答
編輯回答
有點(diǎn)壞

cookie對(duì)應(yīng)服務(wù)器端的session,都有有效期的, 不知道你的上次和這次間隔多長(zhǎng)時(shí)間, 有沒(méi)有試試立即用上次的cookie看看是不是還能登錄?

2018年6月17日 06:43
編輯回答
淺淺

在你的基礎(chǔ)上修改了一下,首先你用cookie登錄是沒(méi)有問(wèn)題的,但是不應(yīng)該再去訪問(wèn)login了,你可以在瀏覽器里試一下登錄成功后,再訪問(wèn)login還是需要輸入用戶名密碼狀態(tài),所以用cookie就跳過(guò)登錄,直接訪問(wèn)主頁(yè)面。我在主頁(yè)面里獲取了一下登錄的賬號(hào),證明是登錄成功了

import requests
from bs4 import BeautifulSoup
from os import remove
from PIL import Image
import pickle
#import http.cookiejar as cookielib
url = 'https://www.douban.com/'
login_url='https://www.douban.com/login'
data={'source':None,
      'remember':'on'
    }

headers = {'Host':'www.douban.com',
           'Referer': 'https://www.douban.com/',
           'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
           'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
           'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
           'Accept-Encoding':'gzip, deflate, br'}

Session=requests.session()
# 讀取是否保存有cookie
try:
    with open('cookie','rb') as f:
        Session.cookies=pickle.load(f)
        #這里我將讀到的cookie輸出
        print(Session.cookies, headers)
        log = True
# 如果沒(méi)有cookie,就讀入用戶輸入
except:
    data['form_email']=input('Please input your account:')
    data['form_password']=input('Please input your password:')
    log = False

# 獲得登陸界面的驗(yàn)證碼
def get_captcha():
    req=Session.get(login_url)
    page_bf=BeautifulSoup(req.text,'html.parser')
    # 尋找驗(yàn)證碼的圖片(有可能不需要驗(yàn)證碼 這時(shí)返回NULL)
    try:
        img_src=page_bf.find('img',id='captcha_image').get('src')
    except:
        return 'NULL','NULL'
    # 如果需要驗(yàn)證碼下載該驗(yàn)證碼并打開(kāi)
    img=requests.get(img_src)
    if img.status_code==200:
        with open('captcha.jpg','wb') as f:
            f.write(img.content)
    image=Image.open('captcha.jpg')
    image.show()
    # 讓用戶根據(jù)驗(yàn)證碼圖片輸入驗(yàn)證碼
    captcha=input('please input the captcha:')
    remove('captcha.jpg')
    # 由于post-data里還要求captcha-id所以我從圖片網(wǎng)址中截取id
    captcha_id=img_src[img_src.find('=')+1:]
    captcha_id=captcha_id[:captcha_id.find('&')]
    return captcha,captcha_id

def login():
    #獲得驗(yàn)證碼和驗(yàn)證碼id
    if not log:
        captcha,captcha_id=get_captcha()
        if captcha!='NULL':
            data['captcha-solution']=captcha
            data['captcha-id']=captcha_id
        # 進(jìn)行登陸
        page_login=Session.post(login_url,data=data,headers=headers)
        # 為了驗(yàn)證是否登陸成功我將登陸返回的頁(yè)面html打印出來(lái)發(fā)現(xiàn)登陸失敗
        #print(page_login.text)
    else:
        page_login=Session.get(url,headers=headers)
    page_login_bf=BeautifulSoup(page_login.text,'html.parser')
    # 如果登陸打印登錄賬號(hào)
    name=page_login_bf.find_all('a',class_='bn-more')
    print(name[0].text) 
    # 將此時(shí)的cookie保存方便下次登陸
    with open('cookie', 'wb') as f:
        pickle.dump(Session.cookies,f)

if __name__=='__main__':
    login()
2018年8月5日 14:09