Learning Scrapy筆記(五)- Scrapy登陸網站

摘要:介紹了使用Scrapy登陸簡單網站的流程,不涉及驗證碼破解javascript

簡單登陸

不少時候,你都會發現你須要爬取數據的網站都有一個登陸機制,大多數狀況下,都要求你輸入正確的用戶名和密碼。如今就模擬這種狀況,在瀏覽器打開網頁:http://127.0.0.1:9312/dynamic,首先打開調試器,而後點擊Elements標籤,查看登陸表單的源代碼html

Image 101

 

再點擊Network標籤,而後在用戶名框裏輸入user,在密碼框裏輸入pass,再點擊login按鈕java

Image 094

 

點擊調試器裏的login頁面,觀察下面的狀況git

Image 095

 

點擊調試器裏的gated頁面,觀察下面的狀況github

Image 096

HTTP的cookie是由服務器發送給瀏覽器,由一些文本和數字組成的字符串,以後瀏覽器訪問服務器的任何請求裏都會帶着這個cookie來標識你的身份和session,從而可以讓你修改在這個網站上的我的信息。web

總的來講,一個登陸操做會包含幾個從瀏覽器到服務器的往返操做,而Scrapy會自動處理這些操做。瀏覽器

 

login.py的源代碼地址:服務器

https://github.com/Kylinlin/scrapybook/blob/master/ch05%2Fproperties%2Fproperties%2Fspiders%2Flogin.pycookie

繼續在上面的名爲easy的spider上擴展代碼,首先將easy.py複製爲login.py,而後作如下修改:session

  • 將spider的名稱修改成login

  • 這裏會使用FormRequest類來登陸,這個類與以前的Request類很類似,只是帶有額外的formdata參數用來傳送登陸的表單信息(用戶名和密碼),爲了使用這個類,須要使用如下語句導入:from scrapy.http import FormRequest

  • 而後用startrequests()函數來代替starturls語句,這樣作的緣由是咱們須要定製更多的參數,最後的函數是這樣的

# Start with a login request
def start_requests(self):
return [
    FormRequest(
      "http://web:9312/dynamic/login",
      formdata={"user": "user", "pass": "pass"} 
#formdata字典裏的key名就是第一張圖中用紅線標註的input標籤中的name值
         )]

就這麼簡單,Scrapy會自動爲咱們處理cookie,只要咱們登陸成功了,它就會像一個瀏覽器同樣自動傳送cookie.

如今運行這個spider:scrapy crawl login

Image 097

能夠看到上面紅線處首先向login頁面提交了一個POST請求,而後重定向到了gated頁面,再用一個GET請求獲得了該頁面,若是用錯了用戶名和密碼,就會獲得錯誤的結果

Image 098

上面是一個極其簡單的登陸機制,大多數網站其實會使用更加複雜的登陸機制,下面的這個例子就使用了隱藏數據

 

帶有隱藏數據的登陸

在瀏覽器打開頁面:http://127.0.0.1:9312/dynamic/nonce,而後用調試器定位到登陸按鈕,能夠看到以下界面

Image 099

與第一個登陸狀況不一樣的是能夠看到這個表單有一個叫作nonce的隱藏字段,當你按下Login按鈕時,向服務器發送的數據包括用戶名和密碼,還有這個屬性的值。你不可能猜到這個屬性的值,由於這是一個一次性的隨機數,這意味着你在Scrapy登陸時須要兩個發送兩個請求,首先獲得表單裏的數據,而後再填充登陸數據,Scrapy已經集成了這些功能。

 

noncelogin.py文件的源代碼地址:

https://github.com/Kylinlin/scrapybook/blob/master/ch05%2Fproperties%2Fproperties%2Fspiders%2Fnoncelogin.py

將以前的login.py文件複製爲noncelogin.py文件,作以下改變:

  • 導入Request:from scrapy.http import Request

  • 將spider的名稱修改成noncelogin

  • 將start_request函數修改以下

#這個函數返回了一個Request,在這個Request中已經指定了回調函數爲parse_welcome,因此會把response傳送到parse_welcome函數上
def start_requests(self):
return [
    Request("http://web:9312/dynamic/nonce",
            callback=self.parse_welcome)
    ]
  • 增長一個parse_welcome函數以下
#接收到了包含表單所有數據的response(此時用戶名和密碼都是空,可是已經獲取到了隱藏字段nonce的值),而後填充用戶名和密碼再登陸
def parse_welcome(self, response):
return FormRequest.from_response(
    response,
    formdata={"user": "user", "pass": "pass"}
    )

運行該spider:scrapy crawl noncelogin

Image 100

以前所說的登陸過程發送了兩個請求指的就是上面標記了順序1和2的兩個請求(一個GET,一個POST)

 

值得注意的是form_response函數

http://doc.scrapy.org/en/1.0/topics/request-response.html#topics-request-response-ref-request-userlogin),這個函數值得仔細研究,若是在登陸頁面有多個表單,此時就要用參數來指定究竟把用戶名和密碼填充到哪一個表單上,同時,函數也默認模擬了對登陸按鈕的點擊行爲,要是網站使用了javascript來控制登陸,此時函數的默認點擊行爲就可能出錯,經過設置dont_click爲True來禁止模擬點擊.

上面只是使用了兩個步驟來登陸,但在面對更加複雜的登陸方式時就須要組織更多的步驟.

相關文章
相關標籤/搜索