Scrapy中的連結提取器與去重工具分析

WBOY
發布: 2023-06-22 09:17:27
原創
1633 人瀏覽過

Scrapy是一個優秀的Python爬蟲框架,它支援並發、分散式、非同步等高階特性,可以幫助開發者更快、更穩定地爬取網路上的資料。在Scrapy中,連結提取器和去重工具是非常重要的組件,用來輔助爬蟲完成自動化的資料抓取和處理。本文將對Scrapy中的連結擷取器和去重工具進行分析,探討它們是如何實現的,以及在Scrapy爬取過程中的應用。

一、連結提取器的作用及實作

連結提取器(Link Extractor)是Scrapy爬蟲框架中的一個自動提取URL連結的工具。在一個完整的爬蟲過程中,往往需要從網頁中提取一些URL鏈接,然後根據這些鏈接進一步進行訪問和處理。連結提取器就是用來實現這個過程的,它可以根據一些規則從網頁中自動提取出鏈接,並將這些鏈接保存到Scrapy的請求隊列中等待後續處理。

在Scrapy中,連結提取器是透過正規表示式或XPath表達式來進行匹配的。 Scrapy提供了兩個連結提取器:基於正規表示式的LinkExtractor和基於XPath表達式的LxmlLinkExtractor。

  1. 基於正規表示式的LinkExtractor

基於正規表示式的LinkExtractor可以透過對網頁中的URL進行正規匹配,自動提取出匹配成功的連結。例如,我們希望從一個網頁中提取所有以http://example.com/ 開頭的鏈接,可以使用以下代碼:

from scrapy.linkextractors import LinkExtractor

link_extractor = LinkExtractor(allow=r'^http://example.com/')
links = link_extractor.extract_links(response)
登入後複製

allow參數指定了一個正則表達式,用來匹配所有以http ://example.com/ 開頭的連結。 extract_links()方法可以提取所有匹配成功的鏈接,並保存在一個Link物件列表中。

Link物件是Scrapy框架中用來表示連結的資料結構,其中包含了連結的URL、標題、anchor文字和連結的類型等資訊。透過這些對象,我們可以很方便地獲取到需要的鏈接,並在Scrapy爬蟲中進一步處理和訪問。

  1. 基於XPath表達式的LxmlLinkExtractor

基於XPath表達式的LxmlLinkExtractor可以透過對網頁中的HTML標籤進行XPath表達式匹配,自動提取出匹配成功的鏈接。例如,我們希望從一個網頁中提取所有class屬性等於"storylink" 的a鏈接,可以使用以下程式碼:

from scrapy.linkextractors import LxmlLinkExtractor

link_extractor = LxmlLinkExtractor(restrict_xpaths='//a[@class="storylink"]')
links = link_extractor.extract_links(response)
登入後複製

restrict_xpaths參數指定了一個XPath表達式,用來匹配所有class屬性等於"storylink " 的a標籤。 LxmlLinkExtractor的使用方式和LinkExtractor類似,可以將提取到的連結保存在一個Link物件清單中。需要注意的是,由於LxmlLinkExtractor使用了lxml庫進行HTML解析,因此需要在專案的設定檔中加入以下程式碼:

# settings.py
DOWNLOAD_HANDLERS = {
    's3': None,
}
登入後複製

以上程式碼可以停用Scrapy中預設的下載器,從而使用lxml庫的HTML解析器。

二、去重工具的作用及實作

在進行Web爬取時,連結去重是非常重要的,因為在大多數情況下,同一個網頁的不同連結是會重複出現的,如果不去重,就會造成重複爬取的問題,浪費頻寬和時間。因此,在Scrapy中引入了去重工具(Duplicate Filter),用來對已經爬取過的連結進行標記和判斷,避免重複訪問。

去重工具的原理是透過將已經訪問過的URL連結保存到一個資料結構中,然後對新的URL連結進行判斷是否已經訪​​問過,如果訪問過,則將該URL連結丟棄,否則將其加入到爬蟲的請求隊列中。 Scrapy內建了許多種去重工具,包括基於記憶體的Set類別去重器、基於磁碟的SQLite3去重器以及基於Redis的去重器等。不同的去重器有不同的適用場景,以下我們以Redis去重器為例進行說明。

  1. 基於Redis的去重器

Redis是一款高效能的NoSQL記憶體資料庫,可以支援分散式、持久化、資料結構豐富等進階特性,非常適合用來實現Scrapy的去重工具。 Scrapy中的Redis去重器可以透過對已經造訪過的URL連結進行標記,避免重複造訪。

Scrapy預設使用的是基於記憶體的Set類別去重器,如果需要使用Redis去重器,可以在專案的設定檔中加入以下程式碼:

# settings.py
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
REDIS_HOST = "localhost"
REDIS_PORT = 6379
登入後複製

其中,DUPEFILTER_CLASS參數指定了去重工具使用的去重策略,這裡我們使用的是scrapy_redis.dupefilter.RFPDupeFilter,該去重器是基於Redis的set資料結構實現的。

SCHEDULER參數指定了調度器使用的調度策略,此處我們使用的是scrapy_redis.scheduler.Scheduler,該調度器是基於Redis的sorted set資料結構實現的。

SCHEDULER_PERSIST參數指定了調度器是否需要在Redis中持久化,即是否需要保存上一次爬取的狀態,從而避免重新爬取已經爬取過的URL。

REDIS_HOST和REDIS_PORT參數分別指定了Redis資料庫的IP位址和連接埠號,如果Redis資料庫不在本機,則需要設定對應的IP位址。

使用Redis去重器之后,需要在爬虫中添加redis_key参数,用来指定Redis中保存URL链接的key名。例如:

# spider.py
class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://example.com']

    custom_settings = {
        'REDIS_HOST': 'localhost',
        'REDIS_PORT': 6379,
        'DUPEFILTER_CLASS': 'scrapy_redis.dupefilter.RFPDupeFilter',
        'SCHEDULER': 'scrapy_redis.scheduler.Scheduler',
        'SCHEDULER_PERSIST': True,
        'SCHEDULER_QUEUE_CLASS': 'scrapy_redis.queue.SpiderPriorityQueue',
        'REDIS_URL': 'redis://user:pass@localhost:6379',
        'ITEM_PIPELINES': {
            'scrapy_redis.pipelines.RedisPipeline': 400,
        },
        'DOWNLOADER_MIDDLEWARES': {
            'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
            'scrapy_useragents.downloadermiddlewares.useragents.UserAgentsMiddleware': 500,
        },
        'FEED_URI': 'result.json',
        'FEED_FORMAT': 'json',
        'LOG_LEVEL': 'INFO',
        'SPIDER_MIDDLEWARES': {
            'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': 300,
        }
    }

    def __init__(self, *args, **kwargs):
        domain = kwargs.pop('domain', '')
        self.allowed_domains = filter(None, domain.split(','))
        self.redis_key = '%s:start_urls' % self.name
        super(MySpider, self).__init__(*args, **kwargs)

    def parse(self, response):
        pass
登入後複製

以上是一个简单的爬虫示例,redis_key参数指定了在Redis中保存URL链接的键名为myspider:start_urls。在parse()方法中,需要编写自己的网页解析代码,提取出需要的信息。

三、总结

链接提取器和去重工具是Scrapy爬虫框架中非常重要的组件,它们可以大大简化我们编写爬虫的工作,并提高爬虫的效率。在使用Scrapy爬虫时,我们可以根据自己的需求选择不同的链接提取器和去重工具,从而实现更为高效和灵活的爬虫功能。

以上是Scrapy中的連結提取器與去重工具分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!