爬取網(wǎng)址:http://example.webscraping.com

1.觀察登陸時(shí)的信息
登陸后可以看到右上方的變化,出現(xiàn)了“歡迎Liu”,同時(shí)也可以在分析工具中看到有一個(gè)post的“method”。如果在chrome中沒(méi)有顯示“method”,可以在欄目中點(diǎn)擊右鍵添加“method”屬性。

選擇這個(gè)表單數(shù)據(jù),然后在Headers的最下方找到Form Data。

另外看回Headers的頭部信息,由于Status code為303,表示頁(yè)面重定向,此時(shí)瀏覽器會(huì)讀取Response Headers中的Location字段,并根據(jù)此路徑再次發(fā)送一個(gè)GET請(qǐng)求。

登陸后可以看到Headers中的Cookie字段,并看到右上方“歡迎Liu”的字樣。

2.使用FormRequest進(jìn)行模擬登陸
① 通過(guò)scrapy shell 進(jìn)行調(diào)試:
scrapy shell http://example.webscraping.com/places/default/user/login
② 然后想辦法獲取表單字段信息:email,password,_formkey,_formname,_next(均為input標(biāo)簽中的name屬性)。其中后三個(gè)字段信息是隱藏的,我們可以通過(guò)查找form元素,然后在Properties中找到這幾個(gè)字段信息。

③ 可以按照下述方式獲取到隱藏的form_data,然后再將賬戶和密碼信息添加進(jìn)字典即可。
from scrapy.http import FormRequest
form_hinfos = response.xpath('//input[@type="hidden"]')
form_name = form_hinfos.xpath('@name').extract()
form_value = form_hinfos.xpath('@value').extract()
form_data = dict(zip(form_name,form_value))
form_data['email'] = 'liushuo@webscraping.com'
form_data['password'] = '12345678'
request = FormRequest('http://example.webscraping.com/places/default/user/login',formdata=form_data)


④ 當(dāng)然,也可以不用捕捉隱藏的input,使用FormRequest的from_response方法即可。使用from_response方法時(shí),需要傳入一個(gè)Response對(duì)象作為第一個(gè)參數(shù),然后from_response方法會(huì)自動(dòng)解析Response對(duì)象中的<form>元素,并將隱藏在<input>中的信息自動(dòng)填入表單數(shù)據(jù)。這樣的話,我們采用form_request方法,只需提供賬戶和密碼即可:
from scrapy.http import FormRequest
form_data = {'email':'liushuo@webscraping.com','password':'12345678'}
request = FormRequest.from_response(response,formdata=form_data)

⑤ 使用上述③或④的方法構(gòu)造好request(均屬于FormRequest對(duì)象)后,就可以提交表單請(qǐng)求,在結(jié)果中可以看到scrapy先發(fā)送一個(gè)Post請(qǐng)求,然后自動(dòng)發(fā)送一個(gè)get請(qǐng)求來(lái)跳轉(zhuǎn)頁(yè)面。最后驗(yàn)證是否登錄,可以看到模擬登陸成功了。實(shí)質(zhì)上,第二個(gè)get請(qǐng)求攜帶了第一個(gè)post請(qǐng)求獲取的Cookie信息,而這個(gè)添加Cookie信息的工作由Scrapy內(nèi)置的下載中間件CookiesMiddleware自動(dòng)完成。

⑥ 可以嘗試提取登陸后的個(gè)人頁(yè)面信息


按照下圖命令即可得到個(gè)人信息。值得注意的是,我們?cè)陧?yè)面上看到keys顯示的是中文,但是通過(guò)scrapy進(jìn)行請(qǐng)求時(shí)獲取的是英文keys信息,所以實(shí)際得到的信息均為英文。這也是我們需要調(diào)用view(response)來(lái)看到最終的Response信息。


3.將上述內(nèi)容進(jìn)行總結(jié),實(shí)現(xiàn)登陸spider
代碼如下:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import FormRequest
class LoginSpider(scrapy.Spider):
name = 'login'
allowed_domains = ['example.webscraping.com']
start_urls = ['http://example.webscraping.com/places/default/user/profile']
##-------------------------------進(jìn)行登錄-------------------------------
#登錄URL
login_url = "http://example.webscraping.com/places/default/user/login"
#改寫start_requests方法
def start_requests(self):
yield scrapy.Request(self.login_url,callback=self.login)
#登錄頁(yè)面的信息處理
def login(self,response):
form_data = {'email': 'liushuo@webscraping.com', 'password': '12345678'}
yield FormRequest.from_response(response, formdata=form_data,callback=self.parse_login)
#登錄成功后,會(huì)自動(dòng)抓取start_urls中的網(wǎng)址,并用parse方法解析。
def parse_login(self,response):
if "Welcome Liu" in response.text:
yield from super().start_requests() #繼承基類的start_requests方法,處理完會(huì)自動(dòng)跳轉(zhuǎn)到parse方法。
##-------------------------------登錄后-------------------------------
#登錄后的信息解析工作
def parse(self, response):
keys = response.xpath('//td[@class="w2p_fl"]/label/text()').re('(.*?):')
values = response.xpath('//td[@class="w2p_fw"]/text()').extract()
yield dict(zip(keys,values))