爬取網(wǎng)址:http://example.webscraping.com
1.觀察登陸時的信息
登陸后可以看到右上方的變化,出現(xiàn)了“歡迎Liu”裳扯,同時也可以在分析工具中看到有一個post的“method”粱玲。如果在chrome中沒有顯示“method”漓拾,可以在欄目中點擊右鍵添加“method”屬性。
選擇這個表單數(shù)據(jù)术浪,然后在Headers的最下方找到Form Data芝此。
另外看回Headers的頭部信息,由于Status code為303因痛,表示頁面重定向婚苹,此時瀏覽器會讀取Response Headers中的Location字段,并根據(jù)此路徑再次發(fā)送一個GET請求鸵膏。
登陸后可以看到Headers中的Cookie字段膊升,并看到右上方“歡迎Liu”的字樣。
2.使用FormRequest進行模擬登陸
① 通過scrapy shell 進行調(diào)試:
scrapy shell http://example.webscraping.com/places/default/user/login
② 然后想辦法獲取表單字段信息:email,password,_formkey,_formname,_next(均為input標簽中的name屬性)谭企。其中后三個字段信息是隱藏的廓译,我們可以通過查找form元素评肆,然后在Properties中找到這幾個字段信息。
③ 可以按照下述方式獲取到隱藏的form_data非区,然后再將賬戶和密碼信息添加進字典即可瓜挽。
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)
④ 當然,也可以不用捕捉隱藏的input征绸,使用FormRequest的from_response方法即可久橙。使用from_response方法時,需要傳入一個Response對象作為第一個參數(shù)管怠,然后from_response方法會自動解析Response對象中的<form>元素淆衷,并將隱藏在<input>中的信息自動填入表單數(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對象)后,就可以提交表單請求她肯,在結(jié)果中可以看到scrapy先發(fā)送一個Post請求佳头,然后自動發(fā)送一個get請求來跳轉(zhuǎn)頁面。最后驗證是否登錄辕宏,可以看到模擬登陸成功了畜晰。實質(zhì)上,第二個get請求攜帶了第一個post請求獲取的Cookie信息瑞筐,而這個添加Cookie信息的工作由Scrapy內(nèi)置的下載中間件CookiesMiddleware自動完成凄鼻。
⑥ 可以嘗試提取登陸后的個人頁面信息
按照下圖命令即可得到個人信息。值得注意的是聚假,我們在頁面上看到keys顯示的是中文块蚌,但是通過scrapy進行請求時獲取的是英文keys信息,所以實際得到的信息均為英文膘格。這也是我們需要調(diào)用view(response)來看到最終的Response信息峭范。
3.將上述內(nèi)容進行總結(jié),實現(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']
##-------------------------------進行登錄-------------------------------
#登錄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)
#登錄頁面的信息處理
def login(self,response):
form_data = {'email': 'liushuo@webscraping.com', 'password': '12345678'}
yield FormRequest.from_response(response, formdata=form_data,callback=self.parse_login)
#登錄成功后瘪贱,會自動抓取start_urls中的網(wǎng)址纱控,并用parse方法解析。
def parse_login(self,response):
if "Welcome Liu" in response.text:
yield from super().start_requests() #繼承基類的start_requests方法菜秦,處理完會自動跳轉(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))