成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

scrapy 進階使用

The question / 1583人閱讀

摘要:下載器負責獲取頁面,然后將它們交給引擎來處理。內(nèi)置了一些下載器中間件,這些中間件將在后面介紹。下載器中間件下載器中間件可以在引擎和爬蟲之間操縱請求和響應(yīng)對象。爬蟲中間件與下載器中間件類似,啟用爬蟲中間件需要一個字典來配置。

前段時間我寫了一篇《scrapy快速入門》,簡單介紹了一點scrapy的知識。最近我的搬瓦工讓墻了,而且我又學(xué)了一點mongodb的知識,所以這次就來介紹一些scrapy的進階知識,做一些真正有用的爬蟲來。

scrapy組件介紹

首先先來介紹一下scrapy的體系結(jié)構(gòu)和組件。

scrapy引擎。顧名思義,它負責調(diào)用爬蟲爬取頁面并將數(shù)據(jù)交給管道來處理。

調(diào)度程序。調(diào)度程序從引擎獲取請求,然后將這些請求交給相應(yīng)的處理者來處理。

下載器。下載器負責獲取web頁面,然后將它們交給引擎來處理。

爬蟲。這是我們要編寫的部分,爬蟲負責從頁面抽取要處理的數(shù)據(jù),然后交由管道來處理。

項目管道。爬蟲抽取出來的數(shù)據(jù),就要交給管道來處理,我們可以編寫自己的管道來清洗、驗證和持久化數(shù)據(jù)。

下載器中間件。下載器中間件在下載器和scrapy引擎之間工作,我們可以利用下載器中間件在將頁面交給爬蟲之前做一些事情。scrapy內(nèi)置了一些下載器中間件,這些中間件將在后面介紹。

爬蟲中間件。爬蟲中間件可以讓我們控制爬蟲的回調(diào)等等。在后面會介紹一些內(nèi)置的爬蟲中間件。

下面是scrapy官網(wǎng)的結(jié)構(gòu)圖,可以幫助我們理解scrapy的體系。

項目(Item)

在以前的爬蟲中我們都是直接返回一個字典,其實這并不是最佳實踐。scrapy提供了一個Item基類,我們可以通過繼承這個類定義自己的結(jié)構(gòu)化數(shù)據(jù),比到處傳遞字典更好。下面是官方文檔的例子。

import scrapy

class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field()
    stock = scrapy.Field()
    last_updated = scrapy.Field(serializer=str)

這些項目類一般都定義在scrapy項目的items.py文件中。定義好之后,在爬蟲中我們就不應(yīng)該在反掌字典了,而是初始化并返回我們自定義的Item對象。

請求和響應(yīng)對象

scrapy通過請求和響應(yīng)對象來處理網(wǎng)頁請求,這部分的文檔可以參考https://doc.scrapy.org/en/latest/topics/request-response.html。請求和響應(yīng)還有一些子類,可以幫助我們完成更具體的工作。例如Request的子類FormRequest就可以幫助我們模擬用戶登錄。

有時候需要模擬用戶登錄,這時候可以使用FormRequest.from_response方法。這時候爬蟲功能稍有變化,parse函數(shù)用來發(fā)送用戶名和密碼,抽取數(shù)據(jù)的操作放在回調(diào)函數(shù)中進行。

import scrapy

class LoginSpider(scrapy.Spider):
    name = "example.com"
    start_urls = ["http://www.example.com/users/login.php"]

    def parse(self, response):
        return scrapy.FormRequest.from_response(
            response,
            formdata={"username": "john", "password": "secret"},
            callback=self.after_login
        )

    def after_login(self, response):
        # 檢查是否登錄成功
        if "authentication failed" in response.body:
            self.logger.error("Login failed")
            return

        # 在這里繼續(xù)爬取數(shù)據(jù)
管道(pipeline)

管道用來處理爬蟲抽取到的數(shù)據(jù),我們可以通過管道對數(shù)據(jù)進行驗證和持久化等操作。管道其實就是帶有process_item(self, item, spider)函數(shù)的一個普通類。下面是scrapy官方文檔的例子,這個例子驗證獲取到的數(shù)據(jù)是否存在價格字段,并丟棄沒有價格字段的無效數(shù)據(jù)。這里還引用了scrapy預(yù)定義的DropItem異常,這個異常必須在管道中拋出,表示管道應(yīng)該丟棄這個數(shù)據(jù)。如果想了解scrapy異常,可以查看官方文檔。

from scrapy.exceptions import DropItem

class PricePipeline(object):

    vat_factor = 1.15

    def process_item(self, item, spider):
        if item["price"]:
            if item["price_excludes_vat"]:
                item["price"] = item["price"] * self.vat_factor
            return item
        else:
            raise DropItem("Missing price in %s" % item)

管道不是一定義好就能用的,還需要在配置文件settings.py中激活。

ITEM_PIPELINES = {
    "myproject.pipelines.PricePipeline": 300,
    "myproject.pipelines.JsonWriterPipeline": 800,
}
將數(shù)據(jù)保存到MongoDB的管道

管道除了驗證數(shù)據(jù),還可以將數(shù)據(jù)保存到數(shù)據(jù)庫中。這時候僅僅一個process_item(self, item, spider)函數(shù)就不夠了。所以操作數(shù)據(jù)庫的管道還應(yīng)該包含幾個函數(shù)用于建立和關(guān)閉數(shù)據(jù)庫連接。

下面的例子也是scrapy官方文檔的例子,演示了持久化數(shù)據(jù)管道的用法。這個管道是從類方法from_crawler(cls, crawler)中初始化出來的,該方法實際上讀取了scrapy的配置文件。這和直接將數(shù)據(jù)庫連接寫在代碼中相比,是更加通用的方式。初始化和關(guān)閉數(shù)據(jù)庫連接的操作都在對應(yīng)的方法中執(zhí)行。

import pymongo

class MongoPipeline(object):

    collection_name = "scrapy_items"

    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get("MONGO_URI"),
            mongo_db=crawler.settings.get("MONGO_DATABASE", "items")
        )

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def close_spider(self, spider):
        self.client.close()

    def process_item(self, item, spider):
        self.db[self.collection_name].insert_one(dict(item))
        return item
使用文件和圖片管道 文件和圖片管道處理過程

除了自己編寫管道之外,scrapy還預(yù)定義了幾個管道,可以幫助我們方便的保存文件和圖片。這些管道有以下特點:

可以避免重復(fù)下載最近的文件。

指定文件保存位置(文件系統(tǒng)或者亞馬遜S3)

對于圖片管道來說還有額外功能:

將圖片轉(zhuǎn)換成常見格式(JPG)和模式(RGB)

生成圖片縮略圖

只下載大于某長寬的圖片

使用文件管道的過程如下:

首先需要Item類中有file_urlsfiles兩個屬性,然后在爬蟲中將想爬取的文件地址放到file_urls屬性中,然后返回

在Item傳遞到文件管道的時候,調(diào)度程序會用下載器將地址對應(yīng)的文件下載下來,將文件屬性(包括保存路徑等)放到files屬性中,file_urlsfiles中是一一對應(yīng)的

使用圖片管道的過程是相似的,不過要操作的屬性是image_urlsimages。

如果你不想使用這幾個屬性,其實屬性名也是可以修改的,需要修改下面四個屬性。

FILES_URLS_FIELD = "field_name_for_your_files_urls"
FILES_RESULT_FIELD = "field_name_for_your_processed_files"
IMAGES_URLS_FIELD = "field_name_for_your_images_urls"
IMAGES_RESULT_FIELD = "field_name_for_your_processed_images"
管道配置

要啟用文件管道和圖片管道,同樣需要激活,當然如果同時激活這兩個管道也是可行的。

ITEM_PIPELINES = {"scrapy.pipelines.images.ImagesPipeline": 1}
# 或者
ITEM_PIPELINES = {"scrapy.pipelines.files.FilesPipeline": 1}

文件和圖片保存位置需要分別指定。

FILES_STORE = "/path/to/valid/dir"
IMAGES_STORE = "/path/to/valid/dir"

文件和圖片管道可以避免下載最近的文件,對應(yīng)的文件過期時間也可以配置,單位是天。

# 120 days of delay for files expiration
FILES_EXPIRES = 120

# 30 days of delay for images expiration
IMAGES_EXPIRES = 30

圖片管道可以在保存圖片的時候同時生成縮略圖,縮略圖配置是一個字典,鍵是縮略圖的名字,值是縮略圖長和寬。

IMAGES_THUMBS = {
    "small": (50, 50),
    "big": (270, 270),
}

最后圖片會保存成下面這樣,圖片的文件名是圖片路徑的SHA1哈希值。

/圖片保存路徑/full/完整圖片.jpg
/圖片保存路徑/thumbs/small/小圖片.jpg
/圖片保存路徑/thumbs/big/中圖片.jpg

如果不想使用SHA1哈希值作為文件名,可以繼承ImagesPipeline基類并重寫file_path函數(shù),這里是另外一位簡書作者的爬蟲項目,他重寫了這個函數(shù)。我們可以作為參考。

如果要過濾小圖片,啟用下面的配置。默認情況下對圖片尺寸沒有約束,所以所有圖片都會下載。

IMAGES_MIN_HEIGHT = 110
IMAGES_MIN_WIDTH = 110

默認情況下文件和圖片管道不支持重定向,遇到需要重定向的鏈接意味著下載失敗,不過我們也可以啟用重定向。

MEDIA_ALLOW_REDIRECTS = True
下載器中間件

下載器中間件可以在scrapy引擎和爬蟲之間操縱請求和響應(yīng)對象。要啟用下載器中間件,啟用下面的配置。這是一個字典,字典的鍵是要啟用的中間件,值會用來比較中間件之間的順序。

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.CustomDownloaderMiddleware": 543,
}

如果希望禁用某些內(nèi)置的中間件,可以將值設(shè)置為None。

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.CustomDownloaderMiddleware": 543,
    "scrapy.downloadermiddlewares.useragent.UserAgentMiddleware": None,
}
編寫自己的下載器中間件

自定義下載器中間件應(yīng)該繼承scrapy.downloadermiddlewares.DownloaderMiddleware類,該類有如下幾個方法,用于操縱請求和響應(yīng),我們只要重寫這幾個方法即可。這幾個方法的作用請參考官方文檔,它們比較復(fù)雜,所以我就不說了。

process_request(request, spider)

process_response(request, response, spider)

process_exception(request, exception, spider)

內(nèi)置的下載器中間件

scrapy內(nèi)置了14個下載器中間件,我簡單介紹一下其中的幾個。詳情參考文檔。

CookiesMiddleware

用于在爬蟲發(fā)起請求和獲取響應(yīng)的時候保持Cookie。

DefaultHeadersMiddleware

用于設(shè)置請求的默認請求頭。

該配置位于DEFAULT_REQUEST_HEADERS,默認值如下。

{
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en",
}
HttpProxyMiddleware

設(shè)置使用的網(wǎng)絡(luò)代理。

UserAgentMiddleware

設(shè)置使用的用戶代理。

爬蟲中間件

與下載器中間件類似,啟用爬蟲中間件需要一個字典來配置。

SPIDER_MIDDLEWARES = {
    "myproject.middlewares.CustomSpiderMiddleware": 543,
}

想要關(guān)閉某個中間件的時候傳遞None值。

SPIDER_MIDDLEWARES = {
    "myproject.middlewares.CustomSpiderMiddleware": 543,
    "scrapy.spidermiddlewares.offsite.OffsiteMiddleware": None,
}
自定義爬蟲中間件

編寫自己的爬蟲中間件需要繼承scrapy.spidermiddlewares.SpiderMiddleware基類,并重寫以下幾個方法。

process_spider_input(response, spider)

process_spider_output(response, result, spider)

process_spider_exception(response, exception, spider)

process_start_requests(start_requests, spider)

內(nèi)置的爬蟲中間件

scrapy內(nèi)置了5個爬蟲中間件,這里我僅介紹一兩個。

DepthMiddleware

該中間件記錄了爬蟲爬取請求地址的深度。

我們可以使用DEPTH_LIMIT來指定爬蟲爬取的深度。

UrlLengthMiddleware

該中間件會過濾掉超出最大允許長度的URL,爬蟲不會訪問這些超長URL。

最大長度通過URLLENGTH_LIMIT配置來指定,默認值是2083。

URLLENGTH_LIMIT = 2083
內(nèi)建服務(wù)

scrapy內(nèi)置了幾個服務(wù),可以讓我們使用scrapy更加方便。

日志

爬蟲類定義了log函數(shù),我們可以方便的在爬蟲類中記錄日志。

import scrapy

class MySpider(scrapy.Spider):

    name = "myspider"
    start_urls = ["https://scrapinghub.com"]

    def parse(self, response):
        self.logger.info("Parse function called on %s", response.url)

日志相關(guān)的配置,點擊可以跳轉(zhuǎn)到官方文檔查看詳細信息。

LOG_FILE

LOG_ENABLED

LOG_ENCODING

LOG_LEVEL

LOG_FORMAT

LOG_DATEFORMAT

LOG_STDOUT

LOG_SHORT_NAMES

發(fā)送電子郵件

有時候我們可能希望爬到一定數(shù)量的數(shù)據(jù)就發(fā)送電子郵件進行提醒。scrapy也內(nèi)置了這個功能。我們可以通過構(gòu)造函數(shù)參數(shù)來創(chuàng)建郵件發(fā)送器。

from scrapy.mail import MailSender
mailer = MailSender(這里是構(gòu)造函數(shù)參數(shù))

也可以從配置文件實例化。

mailer = MailSender.from_settings(settings)

然后調(diào)用send方法就可以發(fā)送郵件了。

mailer.send(to=["[email protected]"], subject="Some subject", body="Some body", cc=["[email protected]"])

電子郵件相關(guān)配置參考官方文檔。

web服務(wù)

這個功能本來是寫在官方文檔內(nèi)建服務(wù)條目下的,但是實際上這個功能已經(jīng)變成了一個多帶帶的項目,需要額外安裝。

pip install scrapy-jsonrpc

然后在擴展中包含這個功能。

EXTENSIONS = {
    "scrapy_jsonrpc.webservice.WebService": 500,
}

還需要在配置中啟用該功能。

JSONRPC_ENABLED = True

然后在爬蟲運行的時候訪問http://localhost:6080/crawler即可查看爬蟲運行情況了。

該項目的其他配置查看其官方文檔。

優(yōu)化爬蟲

爬蟲項目可以通過修改一些配置進行優(yōu)化。

增大并發(fā)數(shù)

并發(fā)數(shù)可以通過下面的配置進行設(shè)置。具體的并發(fā)數(shù)需要根據(jù)服務(wù)器的CPU等設(shè)置來進行更改。一般來說服務(wù)器CPU使用在80%-90%之間利用率比較高。我們可以從并發(fā)數(shù)100開始反復(fù)進行測試。

CONCURRENT_REQUESTS = 100
增大線程池

scrapy通過一個線程池來進行DNS查詢,增大這個線程池一般也可以提高scrapy性能。

REACTOR_THREADPOOL_MAXSIZE = 20
降低日志級別

默認情況下scrapy使用debug級別來打印日志,通過降低日志級別,我們可以減少日志打印,從而提高程序運行速度。

LOG_LEVEL = "INFO"
禁用Cookie

如果不是必須的,我們可以通過禁用Cookie來提高性能。如果需要登錄用戶才能爬取數(shù)據(jù),不要禁用Cookie。

COOKIES_ENABLED = False
關(guān)閉重試

頻繁重試可能導(dǎo)致目標服務(wù)器響應(yīng)緩慢,我們自己訪問不了別人也訪問不了。所以可以考慮關(guān)閉重試。

RETRY_ENABLED = False
減少下載超時

如果網(wǎng)絡(luò)連接比較快的話,我們可以減少下載超時,讓爬蟲卡住的請求中跳出來,一般可以提高爬蟲效率。

DOWNLOAD_TIMEOUT = 15
關(guān)閉重定向

如果不是必要的話,我們可以關(guān)閉重定向來提高爬蟲性能。

REDIRECT_ENABLED = False
自動調(diào)整爬蟲負載

scrapy有一個擴展可以自動調(diào)節(jié)服務(wù)器負載,它通過一個算法來確定最佳的爬蟲延時等設(shè)置。它的文檔在這里。

相關(guān)配置如下,點擊鏈接可以跳轉(zhuǎn)到對應(yīng)文檔。

AUTOTHROTTLE_ENABLED

AUTOTHROTTLE_START_DELAY

AUTOTHROTTLE_MAX_DELAY

AUTOTHROTTLE_TARGET_CONCURRENCY

AUTOTHROTTLE_DEBUG

CONCURRENT_REQUESTS_PER_DOMAIN

CONCURRENT_REQUESTS_PER_IP

DOWNLOAD_DELAY

部署爬蟲

官方文檔介紹了兩種部署爬蟲的方式,可以將爬蟲部署到服務(wù)器上遠程執(zhí)行。第一種是通過Scrapyd開源項目來部署,也是這里要介紹的方式。第二種是通過scrapy公司提供的商業(yè)收費版服務(wù)Scrapy Cloud部署,推薦有財力的公司考慮。

服務(wù)器端

首先服務(wù)器需要安裝scrapyd包,如果是Linux系統(tǒng)還可以考慮使用對應(yīng)的包管理器來安裝。

pip install scrapyd
apt-get install scrapyd

然后運行scrapyd服務(wù),如果使用系統(tǒng)包管理器安裝,那么可能已經(jīng)配置好了systemd文件。

scrapyd
# 或者
systemctl enable scrapyd

scrapyd附帶了一個簡單的web界面可以幫助我們查看爬蟲運行情況,默認情況下訪問http://localhost:6800/來查看這個界面。

scrapyd的配置文件可以是~/.scrapyd.conf或者/etc/scrapyd/scrapyd.conf。下面是一個簡單配置,綁定所有端口,這樣一來從任意位置都可以訪問web界面。

[scrapyd]
bind_address = 0.0.0.0

scrapyd的功能可以查看其API文檔。

客戶端

客戶端如果要上傳爬蟲,可以通過服務(wù)器API的端點addversion.json來實現(xiàn),或者安裝一個簡便工具scrapyd-client。

首先安裝客戶端工具。

pip install scrapyd-client

這個客戶端目前好像有bug,在windows下運行scrapy-deploy命令不會直接執(zhí)行,而是彈出一個文件關(guān)聯(lián)對話框。如果你遇到這種情況,可以找到Python安裝路徑下的腳本路徑(例如C:Program FilesPython36Scripts),然后編寫一個scrapyd-deploy.bat批處理文件,內(nèi)容如下。這樣就可以正常運行了。

@"c:program filespython36python.exe" "c:program filespython36Scriptsscrapyd-deploy" %*

然后切換到項目路徑,編輯項目全局配置文件scrapy.cfg,添加部署路徑。

[deploy]
url = http://192.168.64.136:6800/
project = quotesbot

然后直接運行scrapy-deploy命令,就可以看到項目已經(jīng)成功部署到服務(wù)器上了。

運行爬蟲需要使用scrapyd的API,例如使用curl,可以用下面的命令。

 curl http://192.168.64.136:6800/schedule.json -d project=quotesbot -d spider=toscrape-css

或者使用Jetbrains 系列IDE 2017.3的基于編輯器的HTTP客戶端。

然后點擊Jobs就可以看到爬蟲已經(jīng)開始運行了。如果要查看狀態(tài),點擊右邊的log即可。

以上就是scrapy的進階介紹了,利用這些功能,我們可以編寫更加實用的爬蟲,并將它們部署到服務(wù)器上。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/44529.html

相關(guān)文章

  • 零基礎(chǔ)如何學(xué)爬蟲技術(shù)

    摘要:楚江數(shù)據(jù)是專業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲技術(shù)以供學(xué)習(xí),。本文來源知乎作者路人甲鏈接楚江數(shù)據(jù)提供網(wǎng)站數(shù)據(jù)采集和爬蟲軟件定制開發(fā)服務(wù),服務(wù)范圍涵蓋社交網(wǎng)絡(luò)電子商務(wù)分類信息學(xué)術(shù)研究等。 楚江數(shù)據(jù)是專業(yè)的互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)服務(wù),現(xiàn)整理出零基礎(chǔ)如何學(xué)爬蟲技術(shù)以供學(xué)習(xí),http://www.chujiangdata.com。 第一:Python爬蟲學(xué)習(xí)系列教程(來源于某博主:htt...

    KunMinX 評論0 收藏0
  • 非計算機專業(yè)小白自學(xué)爬蟲全指南(附資源)

    摘要:爬蟲是我接觸計算機編程的入門。練練練本文推薦的資源就是以項目練習(xí)帶動爬蟲學(xué)習(xí),囊括了大部分爬蟲工程師要求的知識點。拓展閱讀一文了解爬蟲與反爬蟲最后,請注意,爬蟲的工作機會相對較少。 爬蟲是我接觸計算機編程的入門。哥當年寫第一行代碼的時候別提有多痛苦。 本文旨在用一篇文章說透爬蟲如何自學(xué)可以達到找工作的要求。 爬蟲的學(xué)習(xí)就是跟著實際項目去學(xué),每個項目會涉及到不同的知識點,項目做多了,自然...

    CarlBenjamin 評論0 收藏0
  • python的scrapy框架爬取懶人聽書網(wǎng)站

    摘要:爬蟲項目的管道文件,用來對中的數(shù)據(jù)進行進一步的加工處理。根據(jù)傳入的正則表達式對數(shù)據(jù)進行提取,返回字符串列表。的作用函數(shù)可創(chuàng)建一個整數(shù)列表,一般用在循環(huán)中。 項目地址:https://github.com/gejinnvshe...微信公眾號:天字一等 爬取懶人聽書平臺書籍的書名、作者名、分類,后續(xù)還會增加爬取音頻 爬蟲用到的框架:scrapy Anaconda是專注于數(shù)據(jù)分析的Pyth...

    CoffeX 評論0 收藏0
  • 快速上手——我用scrapy寫爬蟲(一)

    摘要:寫在前面用寫爬蟲的人很多,的爬蟲框架也很多,諸如和,筆者還是筆記傾向于,本文就用寫一個小爬蟲。本文適用于有一定基礎(chǔ)的,并且對爬蟲有一定了解的開發(fā)者。 寫在前面 用python寫爬蟲的人很多,python的爬蟲框架也很多,諸如pyspider 和 scrapy,筆者還是筆記傾向于scrapy,本文就用python寫一個小爬蟲demo。本文適用于有一定python基礎(chǔ)的,并且對爬蟲有一定了...

    curlyCheng 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<