嗨,昨天完成了一項實戰後,今天來看如何透過Scrapy模擬登入,有些內容是需要登入後才可以看到,這裡有一個範例的網頁: Quotes to Scrape


(Goodreads page)不見了。
現在,回到剛剛的登入頁面,點右鍵檢查:
<form>元素,點擊Login按鈕後,瀏覽器會根據<form>元素的內容發送HTTP請求,可以看到該表單method為post請求方法,action為請求的url。<input>元素,可以看到name為username及password對應到兩個輸入框:
上面有一個<input type="hidden" name="csrf_token">,每重新整理一次頁面,它的value都會改變,雖然它的值不需要使用者填寫,但是在傳送表單的時候缺少就會造成登入驗證失敗,也就是說我們需要先得到這串資訊,就必須登入前先爬取它(token),再把username, password透過FormRequest()將一並代入,如下程式碼:
import scrapy
from bs4 import BeautifulSoup
class NewsSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ['http://quotes.toscrape.com/login']
    def parse(self, response):
        token = response.css("input[name='csrf_token']::attr('value')").extract_first()
        # print(token)
        data = {
            'csrf_token':token,
            'username':'user',
            'password':'123'
        }
        yield scrapy.FormRequest(url=self.start_urls[0], formdata=data, callback=self.parse_quotes)
    def parse_quotes(self, response):
        soup = BeautifulSoup(response.text)
        quotes = soup.select('div.quote')
        for q in quotes:
            print(q.select('a'))
假設我們直接在Quotes to Scrape頁面直接爬(例如以下程式碼),會發現結果會沒有包含(Goodreads page)內容:
class NewsSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ['http://quotes.toscrape.com/']
    def parse(self, response):
        soup = BeautifulSoup(response.text)
        quotes = soup.select('div.quote')
        for q in quotes:
            print(q.select('a'))
好的,這就是模擬登入了的說明了!那我們明天見啦!