Scrapy蜘蛛(Spider)


Spider是負責定義如何遵循通過網站的連結並提取網頁中的資訊的類。
Scrapy預設的 Spider 如下:

scrapy.Spider

它是所有其他的蜘蛛(spider)都必須繼承的類。它具有以下類:
class scrapy.spiders.Spider
下面的表顯示了 scrapy.Spider 類的欄位:
S.N. 欄位 & 描述
1 name
這是 spider 的名字
2 allowed_domains
它是允許 spider 抓取域名稱的列表
3 start_urls
這是供以後蜘蛛將開始抓取的URL列表的根
4 custom_settings
這些設定在蜘蛛執行時會從專案範圍內覆蓋組態
5 crawler
它是連結到 spider 範例系結的 Crawler 物件的屬性
6 settings
這些是執行一個 spider 的設定
7 logger
它是用來傳送紀錄檔訊息的 python 記錄器
8 from_crawler(crawler,*args,**kwargs)
它是由 spider 建立的一個類方法。引數是:
  • crawler: 抓取工具到 spider 範例將被繫結;

  • args(list): 這些引數傳遞給方法: _init_();

  • kwargs(dict): 這些關鍵字引數傳遞給方法: _init_().

9 start_requests()
如果不指定特定的URL,蜘蛛會開啟抓取,Scrapy呼叫start_requests()方法
10 make_requests_from_url(url)
它是用於將URL網址轉換為請求方法
11 parse(response)
這個方法處理響應並返回廢棄資料
12 log(message[,level,component])
這個方法會通過蜘蛛傳送紀錄檔記錄資訊
13 closed(reason)
這種方法在當蜘蛛關閉時呼叫

Spider引數

Spider 引數用於指定起始URL和使用帶有-a選項的抓取命令來傳遞,如下圖所示:
scrapy crawl first_scrapy -a group = accessories
下面的程式碼範例顯示蜘蛛是如何接收引數的:
import scrapy

class FirstSpider(scrapy.Spider):
    name = "first"

    def __init__(self, group=None, *args, **kwargs):
        super(FirstSpider, self).__init__(*args, **kwargs)
        self.start_urls = ["https://www.tw511.com/group/%s" % group]

通用Spider

您可以使用通用蜘蛛來建立子類蜘蛛。他們的目的是要根據一定的規則來提取所有在網站上的所有連結的資料。

例如:
我們假設專案有以下的欄位:
import scrapy
from scrapy.item import Item, Field
	
class First_scrapyItem(scrapy.Item):
    product_title = Field()
    product_link = Field()
    product_description = Field()

CrawlSpider

CrawlSpider定義了一套規律可循的聯絡,並取消多個頁面。它具有以下類:
class scrapy.spiders.CrawlSpider
以下是CrawlSpider類的屬性:

rules

這是規則物件的列表,它定義了爬網程式如何抓取下面的連結。
下面的表顯示了CrawlSpider類的規則:
S.N.
規則和說明
1 LinkExtractor
它指定蜘蛛如何跟隨連結和提取資料;
2 callback
它是在每一頁提取之後被呼叫; 
3 follow
它指定是否繼續跟蹤連結;

parse_start_url(response)

它通過允許解析初步回應返回專案或請求物件。

注意: 請務必重新命名等函式解析而不是編寫規則,因為解析函式用於CrawlSpider來實現它的邏輯。

例如:

讓我們看看下面的例子開始演示蜘蛛爬行 example.com 首頁,使用 parse_items 方法收集所有頁面上的連結和詞組:

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

class DemoSpider(CrawlSpider):
    name = "demo"
    allowed_domains = ["www.tw511.com"]
    start_urls = ["https://www.tw511.com"]

    rules = (
    Rule(LinkExtractor(allow =(), restrict_xpaths = ("//div[@class = 'next']",)), callback = "parse_item", follow = True),
    )

    def parse_item(self, response):
        item = DemoItem()
        item["product_title"] = response.xpath("a/text()").extract()
        item["product_link"] = response.xpath("a/@href").extract()
        item["product_description"]  = response.xpath("div[@class='desc']/text()").extract()
        return items

XMLFeedSpider

它是從XML的Feed提取並遍歷節點的蜘蛛的基礎類別。它具有以下類:
class scrapy.spiders.XMLFeedSpider
下表顯示了用於設定iterator和標記名稱的類屬性:
S.N.
屬性和說明
1 iterator
它定義將要使用的疊代器。它可以是iternodes,HTML或XML。預設為:iternodes
2 itertag
它使用節點名稱的字串進行疊代
3 namespaces
它是由(prefix, uri)元組使用register_namespace()方法自動註冊名稱空間的列表中定義
4 adapt_response(response)
它接收響應,並儘快在開始解析之前從蜘蛛中介軟體修改響應體
5 parse_node(response,selector)
它接收到響應和選擇器,在每個節點匹配提供標簽名時呼叫
注意:如果不重寫此方法,蜘蛛將不起作用
6 process_results(response,results)
它由蜘蛛返回結果和響應列表

CSVFeedSpider

它通過它的每行的疊代,收到一個CSV檔案作為響應,並呼叫 parse_row() 方法。它具有以下類:
class scrapy.spiders.CSVFeedSpider
下表顯示了可設定關於CSV檔案的選項:
S.N.
選項及說明
1 delimiter
它是包含每個欄位使用逗號(「,」)分隔的字串
2 quotechar
這是一個包含每個欄位使用引號('"')字串
3 headers
它是一個可從中可以提取欄位語句的列表
4 parse_row(response,row)
它接收一個響應,並每一行使用報頭鍵

CSVFeedSpider 範例:

from scrapy.spiders import CSVFeedSpider
from demoproject.items import DemoItem

class DemoSpider(CSVFeedSpider):
    name = "demo"
    allowed_domains = ["www.tw511.com"]
    start_urls = ["https://www.tw511.com/feed.csv"]
    delimiter = ";"
    quotechar = "'"
    headers = ["product_title", "product_link", "product_description"]

    def parse_row(self, response, row):
        self.logger.info("This is row: %r", row)

        item = DemoItem()
        item["product_title"] = row["product_title"]
        item["product_link"] = row["product_link"]
        item["product_description"] = row["product_description"]
        return item

SitemapSpider

站點地圖(sitemap)幫助蜘蛛通過 robots.txt 的定位網址並抓取網站。它有以下類:

class scrapy.spiders.SitemapSpider
下面的表顯示了SitemapSpider的欄位:
S.N.
欄位及說明
1 sitemap_urls
要抓取指向網站地圖的URL列表
2 sitemap_rules
這是一個元組列表 (regex, callback) ,其中,正規表示式是正規表示式,回撥是用來處理的URL匹配的正規表示式
3 sitemap_follow
這是網站地圖的正規表示式的跟蹤列表
4 sitemap_alternate_links
指定要跟蹤一個URL備用鏈路

SitemapSpider 範例:

下面是 SitemapSpider 處理所有的網址:
from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
    urls = ["https://www.tw511.com/sitemap.xml"]

    def parse(self, response):
        # You can scrap items here
下面是 SitemapSpider 處理某些URL與回撥:
from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
    urls = ["https://www.tw511.com/sitemap.xml"]
    rules = [
        ("/item/", "parse_item"),
        ("/group/", "parse_group"),
    ]

    def parse_item(self, response):
        # you can scrap item here

    def parse_group(self, response):
        # you can scrap group here  

下面的程式碼顯示了跟蹤站點地圖,在 robots.txt 中的網址有 /sitemap_company:

from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
    urls = ["https://www.tw511.com/robots.txt"]
    rules = [
        ("/company/", "parse_company"),
    ]
    sitemap_follow = ["/sitemap_company"]

    def parse_company(self, response):
        # you can scrap company here
您甚至可以將 SitemapSpider 與其他網址相結合如下圖所示:
from scrapy.spiders import SitemapSpider

class DemoSpider(SitemapSpider):
    urls = ["https://www.tw511.com/robots.txt"]
    rules = [
        ("/company/", "parse_company"),
    ]

    other_urls = ["https://www.tw511.com/contact-us"]

    def start_requests(self):
        requests = list(super(DemoSpider, self).start_requests())
        requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]
        return requests

    def parse_company(self, response):
        # you can scrap company here...
		
    def parse_other(self, response):
        # you can scrap other here...