天天看點

Scrapy--CrawlSpiderCrawlSpider簡介CrawlSpider實戰

目錄

CrawlSpider簡介

rules

parse_start_url(response)

Rule(爬取規則)

Link Extractors

CrawlSpider實戰

建立項目

定義Item

建立CrawlSpider

編寫Pipeline

啟動爬蟲

CrawlSpider簡介

class scrapy.spiders.CrawlSpider
           

 CrawlSpider 是 Spider 的一個子類,不僅天生就繼承了Spider的所有特性,還在Spider的基礎上提供了一些擴充能力:允許使用者定義一些規則(Rule)來跟進那些需要繼續爬取的URL(連結)。

除了從Spider繼承過來的屬性外,CrawlSpider 還提供了一個新的屬性:

rules

一個包含一個(或多個) Rule 對象的集合(list)。 每個 Rule 對爬取網站的一類URL連結定義了特定表現。 如果多個Rule比對了相同的連結,則根據他們在本屬性中被定義的順序,第一個會被使用。

CrawlSpider 也提供了一個可複寫(overrideable)的方法:

parse_start_url(response)

當start_url的請求傳回時,該方法被調用。 該方法分析最初的傳回值并必須傳回一個 Item 對象或者 一個 Request 對象或者 一個可疊代的包含二者對象。

Rule(爬取規則)

class scrapy.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)
           

scrapy.spiders.Rule各項參數:

  • link_extractor 是一個 Link Extractor 對象,用于定義需要提取的連結。
  • callback 是一個callable 或 string ( 該spider 中同名的函數将作為回調函數被調用)。 從link_extractor中每擷取到比對的連結時将會調用該函數。該回調函數接受一個response作為其第一個參數, 并傳回一個包含 Item 以及(或) Request 對象(或者這兩者的子類)的清單(list)。
  • cb_kwargs 包含傳遞給回調函數的參數(keyword argument)的字典。
  • follow 是一個布爾(boolean)值,指定了根據該規則從response提取的連結是否需要跟進。 如果 callback 為 None, follow 預設設定為 True ,否則預設為 False 。
  • process_links 是一個callable或string(該spider 中同名的函數将作為回調函數被調用)。 從link_extractor 中擷取到連結清單時将會調用該函數。該方法主要用來過濾。
  • process_request 是一個callable或string(該spider 中同名的函數将作為回調函數被調用)。 該規則提取到每個request時都會調用該函數。該函數必須傳回一個request或者None。 (用來過濾request)

警告:當編寫爬蟲規則時,請避免使用 parse 作為回調函數。 由于 CrawlSpider 使用 parse 方法來實作其邏輯,如果 您覆寫了 parse 方法,crawl spider 将會運作失敗。 

Link Extractors

class scrapy.linkextractors.LinkExtractor
           

Link Extractors 用來從網頁(scrapy.http.Response 對象)中抽取最終将會被follow 的連結。

Link Extractors常用參數:

  • allow 滿足括号中“正規表達式”的URL會被提取,如果為空,則全部比對
  • deny 滿足括号中“正規表達式”的URL一定不提取(優先級高于 allow )
  • allow_domains 會被提取的連結的 domains
  • deny_domains 一定不會被提取連結的domains
  • restrict_xpaths 使用 xpath表達式,和 allow 共同作用過濾連結,即 xpath 滿足範圍内的 URL 會被提取

Scrapy提供了 scrapy.linkextractors import LinkExtractor , 但你可以通過實作一個簡單的接口建立自己定制的Link Extractor來滿足需求。

每個link extractor有唯一的公共方法是 extract_links ,它接收一個 Response 對象,并傳回一個 scrapy.link.Link 對象。Link Extractors,要執行個體化一次并且 extract_links 方法會根據不同的response調用多次提取連結。

CrawlSpider實戰

本文将以爬取起點中文網中所有的免費文章(标題、簡介、作者、文章位址)為例對CrawlSpider的用法進行示例。

建立項目

打開一個 Windows指令行視窗,切換到你打算存儲代碼的目錄中(本例中是 D:\scrapy),運作下列指令: 

d:\scrapy>scrapy startproject qidian_crawl
           

執行完該指令後,将會建立包含下列内容的 qidian_crawl 目錄:

Scrapy--CrawlSpiderCrawlSpider簡介CrawlSpider實戰

定義Item

在 items.py 中定義所需爬取的文章字段(标題、簡介、作者、文章位址)。

import scrapy

class QidianCrawlItem(scrapy.Item):
    title = scrapy.Field() # 标題
    intro = scrapy.Field() # 簡介
    author = scrapy.Field() # 作者
    url = scrapy.Field() # 文章位址
           

建立CrawlSpider

CrawlSpider 的建立方法跟普通的Spider類似,在Windows指令行執行如下指令完成建立:

d:\scrapy>cd qidian_crawl
d:\scrapy\qidian_crawl>scrapy genspider -t crawl qidian qidian.com
           

執行完該指令後,将會在 qidian_crawl 的 spiders 目錄下生成一個 qidian.py 檔案 :

Scrapy--CrawlSpiderCrawlSpider簡介CrawlSpider實戰

我們要在 qidian.py 檔案中編寫爬取網站的連結URL提取和處理規則。

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from qidian_crawl.items import QidianCrawlItem


class QidianSpider(CrawlSpider):  # 繼承自 class CrawlSpider(Spider)
    name = 'qidian'  # 爬蟲名稱,啟動爬蟲時使用:scrapy crawl <爬蟲名稱>
    allowed_domains = ['qidian.com']  # 允許爬取的範圍
    '''
    爬蟲的起始位址,其響應可使用 parse_start_url(response) 進行專門處理。
    '''
    start_urls = [
        'https://www.qidian.com/free/all?orderId=&vip=hidden&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=1&page=1']

    def start_requests(self):  # 啟動時設定 Cookies ,Spider 的特性
        cookies = 'e1=%7B%22pid%22%3A%22qd_P_xiangqing%22%2C%22eid%22%3A%22%22%7D; e2=%7B%22pid%22%3A%22qd_P_xiangqing%22%2C%22eid%22%3A%22%22%2C%22l1%22%3A4%7D; _csrfToken=0oIxR8Di1jdqyiUCGJAhBLcm6a0kyMuvmrq0vyjI; newstatisticUUID=1556264399_358226677; e2=%7B%22pid%22%3A%22qd_P_free%22%2C%22eid%22%3A%22qd_C44%22%7D; e1=%7B%22pid%22%3A%22qd_P_limitfree%22%2C%22eid%22%3A%22qd_E01%22%2C%22l1%22%3A4%7D'
        cookies = {i.split('=')[0]: i.split('=')[1] for i in cookies.split('; ')}
        yield scrapy.Request(self.start_urls[0], cookies=cookies)

    '''
    連結URL的提取和處理規則
    '''
    rules = (
        Rule(LinkExtractor(allow=r'//book.qidian.com/info/\d+'), callback='parse_item', follow=False),
        Rule(LinkExtractor(
            allow=r'//www\.qidian\.com/free/all\?orderId=&vip=hidden&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=1&page=\d+'),
            follow=True),
    )

    def parse_item(self, response):  # 回調函數
        item = QidianCrawlItem()
        item['url'] = response.request._url
        item['title'] = response.xpath("//div[@class='book-info ']/h1/em/text()").extract_first()
        item['author'] = response.xpath("//div[@class='book-info ']/h1/span/a/text()").extract_first()
        item['intro'] = response.xpath("//div[@class='book-info ']//p[@class='intro']/text()").extract_first()
        yield item
           

編寫Pipeline

CrawlSpider中收集的Item将會被傳遞到Item Pipeline中再次進行處理,在這裡我們将提取到的QidianCrawlItem資料儲存到檔案中。

# -*- coding: utf-8 -*-

from qidian_crawl.items import QidianCrawlItem
import json

class QidianCrawlPipeline(object):
    def process_item(self, item, spider):
        if isinstance(item, QidianCrawlItem):  # 僅處理 QidianCrawlItem ,其他Item不予處理,直接傳回
            # 将文章資料儲存到檔案
            with open('qidian.txt', 'a', encoding='utf-8') as f:
                json.dump(dict(item), f, ensure_ascii=False, indent=2)
        return item
           

在settings.py 中激活 Pipeline,并設定好 User-Agent 。

# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'qidian_crawl.pipelines.QidianCrawlPipeline': 300,
}

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False
           

啟動爬蟲

至此示例項目就算配置完成了,在Windows指令行執行如下指令來啟動爬蟲:

d:\scrapy\qidian_crawl>scrapy crawl qidian
           

待程式執行完成後,會在Scrapy項目的根目錄下生成一個qidian.txt文本檔案。

Scrapy--CrawlSpiderCrawlSpider簡介CrawlSpider實戰

qidian.txt 中的前兩條文章内容如下:

Scrapy--CrawlSpiderCrawlSpider簡介CrawlSpider實戰

繼續閱讀