為什么要模擬登錄
有些網(wǎng)站是需要登錄之后才能訪問(wèn)的,即便是同一個(gè)網(wǎng)站,在用戶(hù)登錄前后頁(yè)面所展示的內(nèi)容也可能會(huì)大不相同,例如,未登錄時(shí)訪問(wèn)Github首頁(yè)將會(huì)是以下的注冊(cè)頁(yè)面:

然而,登錄后訪問(wèn)Github首頁(yè)將包含如下頁(yè)面內(nèi)容:

如果我們要爬取的是一些需要登錄之后才能訪問(wèn)的頁(yè)面數(shù)據(jù)就需要模擬登錄了。通常我們都是利用的 Cookies 來(lái)實(shí)現(xiàn)模擬登錄,在Scrapy中,模擬登陸網(wǎng)站一般有如下兩種實(shí)現(xiàn)方式:
(1) 請(qǐng)求時(shí)攜帶Cookies
(2) 發(fā)送Post請(qǐng)求獲取Cookies
請(qǐng)求時(shí)攜帶Cookies
對(duì)于一些Cookies過(guò)期時(shí)間很長(zhǎng)的不規(guī)范網(wǎng)站,如果我們能夠在Cookies過(guò)期之前爬取到所有我們想要的數(shù)據(jù),可以考慮在請(qǐng)求時(shí)直接將Cookies信息帶上來(lái)模擬用戶(hù)登錄。
以下是模擬登錄Github的示例代碼:
# -*- coding: utf-8 -*-
import scrapy
import re
class TmallLoginSpider(scrapy.Spider):
name = 'github_login3'
allowed_domains = ['github.com']
start_urls = ['https://github.com/']
def start_requests(self): # 請(qǐng)求時(shí)攜帶Cookies
cookies = '_ga=GA1.2.363045452.1554860671; tz=Asia%2FShanghai; _octo=GH1.1.1405577398.1554860677; _device_id=ee3ff12512668a1f9dc6fb33e388ea20; ignored_unsupported_browser_notice=false; has_recent_activity=1; user_session=5oxrsfsZCor1iJFCgRXXyeAXd8hcmzEUGh70-xHWLjQkT62Q; __Host-user_session_same_site=5oxrsfsZCor1iJFCgRXXyeAXd8hcmzEUGh70-xHWLjQkT62Q; logged_in=yes; dotcom_user=pengjunlee; _gat=1'
cookies = {i.split('=')[0]: i.split('=')[1] for i in cookies.split('; ')}
yield scrapy.Request(self.start_urls[0], cookies=cookies)
def parse(self, response): # 驗(yàn)證是否請(qǐng)求成功
print(re.findall('Learn Git and GitHub without any code!',response.body.decode()))
執(zhí)行爬蟲(chóng)后,后臺(tái)部分日志截圖如下:

發(fā)送Post請(qǐng)求模擬登錄
Scrapy還提供了兩種通過(guò)發(fā)送Post請(qǐng)求來(lái)獲取Cookies的方法。
scrapy.FormRequest()
使用scrapy.FormRequest()發(fā)送Post請(qǐng)求實(shí)現(xiàn)模擬登陸,需要人為找出登錄請(qǐng)求的地址以及構(gòu)造出登錄時(shí)所需的請(qǐng)求數(shù)據(jù)。
使用scrapy.FormRequest()模擬登錄Github的示例代碼:
# -*- coding: utf-8 -*-
import scrapy
import re
class GithubLoginSpider(scrapy.Spider):
name = 'github_login'
allowed_domains = ['github.com']
start_urls = ['https://github.com/login']
def parse(self, response): # 發(fā)送Post請(qǐng)求獲取Cookies
authenticity_token = response.xpath('//input[@name="authenticity_token"]/@value').extract_first()
utf8 = response.xpath('//input[@name="utf8"]/@value').extract_first()
commit = response.xpath('//input[@name="commit"]/@value').extract_first()
form_data = {
'login': 'pengjunlee@163.com',
'password': '123456',
'webauthn-support': 'supported',
'authenticity_token': authenticity_token,
'utf8': utf8,
'commit': commit}
yield scrapy.FormRequest("https://github.com/session", formdata=form_data, callback=self.after_login)
def after_login(self, response): # 驗(yàn)證是否請(qǐng)求成功
print(re.findall('Learn Git and GitHub without any code!', response.body.decode()))
從后臺(tái)日志不難看出,Scrapy 在請(qǐng)求完 https://github.com/session 后,自動(dòng)幫我們重定向到了Github首頁(yè)。

scrapy.FormRequest.from_response()
scrapy.FormRequest.from_response()使用起來(lái)比 scrapy.FormRequest()更加簡(jiǎn)單方便,我們通常只需要提供用戶(hù)相關(guān)信息(賬戶(hù)和密碼)即可,scrapy.FormRequest.from_response()將通過(guò)模擬點(diǎn)擊為我們填充好其他的表單字段并提交表單。
使用scrapy.FormRequest.from_response()模擬登錄Github的示例代碼:
# -*- coding: utf-8 -*-
import scrapy
import re
class GithubLogin2Spider(scrapy.Spider):
name = 'github_login2'
allowed_domains = ['github.com']
start_urls = ['https://github.com/login']
def parse(self, response): # 發(fā)送Post請(qǐng)求獲取Cookies
form_data = {
'login': 'pengjunlee@163.com',
'password': '123456'
}
yield scrapy.FormRequest.from_response(response,formdata=form_data,callback=self.after_login)
def after_login(self,response): # 驗(yàn)證是否請(qǐng)求成功
print(re.findall('Learn Git and GitHub without any code!',response.body.decode()))
scrapy.FormRequest.from_response()方法還可以傳入其他參數(shù)來(lái)幫我們更加精確的指定表單元素:
'''
response (Response object) – 包含表單HTML的響應(yīng),將用來(lái)對(duì)表單的字段進(jìn)行預(yù)填充
formname (string) – 如果設(shè)置了該值,name 等于該值的表單將被使用
formid (string) – 如果設(shè)置了該值,id 等于該值的表單將被使用
formxpath (string) – 如果設(shè)置了該值,匹配該 xpath 的第一個(gè)表單將被使用
formcss (string) – 如果設(shè)置了該值,匹配該 css選擇器的第一個(gè)表單將被使用
formnumber (integer) – 索引值等于該值的表單將被使用,默認(rèn)第一個(gè)(索引值為 0 )
formdata (dict) – 傳入的表單數(shù)據(jù),將覆蓋form 元素中已經(jīng)存在的值
clickdata (dict) – 用于查找可點(diǎn)擊控件的屬性值
dont_click (boolean) – 如果設(shè)置為 True,將不點(diǎn)擊任何元素,直接提交表單數(shù)據(jù)
'''
參考文章
https://doc.scrapy.org/en/latest/topics/request-response.html
到此這篇關(guān)于Scrapy實(shí)現(xiàn)模擬登錄的示例代碼的文章就介紹到這了,更多相關(guān)Scrapy 模擬登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- python基于scrapy爬取京東筆記本電腦數(shù)據(jù)并進(jìn)行簡(jiǎn)單處理和分析
- Scrapy元素選擇器Xpath用法匯總
- Django結(jié)合使用Scrapy爬取數(shù)據(jù)入庫(kù)的方法示例
- python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞
- python爬蟲(chóng)scrapy框架之增量式爬蟲(chóng)的示例代碼
- 一文讀懂python Scrapy爬蟲(chóng)框架
- Python爬蟲(chóng)之教你利用Scrapy爬取圖片