日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

crawler(七):Scrapy的Request和Response、Files Pipeline、Images Pipeline

發(fā)布時(shí)間:2023/12/8 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 crawler(七):Scrapy的Request和Response、Files Pipeline、Images Pipeline 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

請(qǐng)求和響應(yīng)

Scrapy的Request 和Response對(duì)象用于爬網(wǎng)網(wǎng)站。
通常,Request對(duì)象在爬蟲(chóng)程序中生成并傳遞到系統(tǒng),直到它們到達(dá)下載程序,后者執(zhí)行請(qǐng)求并返回一個(gè)Response對(duì)象,該對(duì)象返回到發(fā)出請(qǐng)求的爬蟲(chóng)程序。

爬蟲(chóng)->Request:創(chuàng)建 Request->Response:獲取下載數(shù)據(jù) Response->爬蟲(chóng):數(shù)據(jù)


兩個(gè)類(lèi)Request和Response類(lèi)都有一些子類(lèi),它們添加基類(lèi)中不需要的功能。這些在下面的請(qǐng)求子類(lèi)和 響應(yīng)子類(lèi)中描述。

class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback])

一個(gè)Request對(duì)象表示一個(gè)HTTP請(qǐng)求,它通常是在爬蟲(chóng)生成,并由下載執(zhí)行,從而生成Response。
常用參數(shù):

  • url(string) - 此請(qǐng)求的網(wǎng)址
  • callback(callable) - 將使用此請(qǐng)求的響應(yīng)(一旦下載)作為其第一個(gè)參數(shù)調(diào)用的函數(shù)。有關(guān)更多信息,請(qǐng)參閱下面的將附加數(shù)據(jù)傳遞給回調(diào)函數(shù)。如果請(qǐng)求沒(méi)有指定回調(diào),parse()將使用spider的 方法。請(qǐng)注意,如果在處理期間引發(fā)異常,則會(huì)調(diào)用errback。
  • method(string) - 此請(qǐng)求的HTTP方法。默認(rèn)為’GET’。
  • meta(dict) - 屬性的初始值Request.meta。如果給定,在此參數(shù)中傳遞的dict將被淺復(fù)制。
  • headers(dict) - 這個(gè)請(qǐng)求的頭。dict值可以是字符串(對(duì)于單值標(biāo)頭)或列表(對(duì)于多值標(biāo)頭)。如果 None作為值傳遞,則不會(huì)發(fā)送HTTP頭。
  • body(str或unicode) - 請(qǐng)求體。如果unicode傳遞了a,那么它被編碼為 str使用傳遞的編碼(默認(rèn)為utf-8)。如果 body沒(méi)有給出,則存儲(chǔ)一個(gè)空字符串。不管這個(gè)參數(shù)的類(lèi)型,存儲(chǔ)的最終值將是一個(gè)str(不會(huì)是unicode或None)。
  • cookie(dict或list) - 請(qǐng)求cookie。這些可以以兩種形式發(fā)送。
  • dont_filter(boolean) - 表示此請(qǐng)求不應(yīng)由調(diào)度程序過(guò)濾。當(dāng)您想要多次執(zhí)行相同的請(qǐng)求時(shí)忽略重復(fù)過(guò)濾器時(shí)使用。小心使用它,或者你會(huì)進(jìn)入爬行循環(huán)。默認(rèn)為False。
  • priority(int) - 此請(qǐng)求的優(yōu)先級(jí)(默認(rèn)為0)。調(diào)度器使用優(yōu)先級(jí)來(lái)定義用于處理請(qǐng)求的順序。具有較高優(yōu)先級(jí)值的請(qǐng)求將較早執(zhí)行。允許負(fù)值以指示相對(duì)低優(yōu)先級(jí)。
  • encoding(string) - 此請(qǐng)求的編碼(默認(rèn)為’utf-8’)。此編碼將用于對(duì)URL進(jìn)行百分比編碼,并將正文轉(zhuǎn)換為str(如果給定unicode)。

Request中meta參數(shù)的作用是傳遞信息給下一個(gè)函數(shù),使用過(guò)程可以理解成:

把需要傳遞的信息賦值給這個(gè)叫meta的變量, 但meta只接受字典類(lèi)型的賦值,因此 要把待傳遞的信息改成“字典”的形式,即: meta={'key1':value1,'key2':value2}如果想在下一個(gè)函數(shù)中取出value1, 只需得到上一個(gè)函數(shù)的meta['key1']即可, 因?yàn)閙eta是隨著Request產(chǎn)生時(shí)傳遞的, 下一個(gè)函數(shù)得到的Response對(duì)象中就會(huì)有meta, 即response.meta, 取value1則是value1=response.meta['key1'] class example(scrapy.Spider):name='example'allowed_domains=['example.com']start_urls=['http://www.example.com']def parse(self,response):#從start_urls中分析出的一個(gè)網(wǎng)址賦值給urlurl=response.xpath('.......').extract()#ExamleClass是在items.py中定義的,下面會(huì)寫(xiě)出。"""記住item本身是一個(gè)字典"""item=ExampleClass()item['name']=response.xpath('.......').extract()item['htmlurl']=response.xpath('.......').extract()"""通過(guò)meta參數(shù),把item這個(gè)字典,賦值給meta中的'key'鍵(記住meta本身也是一個(gè)字典)。Scrapy.Request請(qǐng)求url后生成一個(gè)"Request對(duì)象",這個(gè)meta字典(含有鍵值'key','key'的值也是一個(gè)字典,即item)會(huì)被“放”在"Request對(duì)象"里一起發(fā)送給parse2()函數(shù) """yield Request(url,meta={'key':item},callback='parse2')def parse2(self,response):item=response.meta['key']"""這個(gè)response已含有上述meta字典,此句將這個(gè)字典賦值給item,完成信息傳遞。這個(gè)item已經(jīng)和parse中的item一樣了"""item['text']=response.xpath('.......').extract()#item共三個(gè)鍵值,到這里全部添加完畢了yield item

meta是淺復(fù)制,必要時(shí)需要深復(fù)制。

import copy meta={'key':copy.deepcopy('value')}

meta是一個(gè)dict,主要是用解析函數(shù)之間傳遞值,一種常見(jiàn)的情況:在parse中給item某些字段提取了值,但是另外一些值需要在parse_item中提取,這時(shí)候需要將parse中的item傳到parse_item方法中處理,顯然無(wú)法直接給parse_item設(shè)置而外參數(shù)。 Request對(duì)象接受一個(gè)meta參數(shù),一個(gè)字典對(duì)象,同時(shí)Response對(duì)象有一個(gè)meta屬性可以取到相應(yīng)request傳過(guò)來(lái)的meta。所以解決上述問(wèn)題可以這樣做:

def parse(self, response):# item = ItemClass()yield Request(url, meta={'item': item}, callback=self.parse_item) def parse(self, response):item = response.meta['item']item['field'] = valueyield item

request和response之間如何傳參

有些時(shí)候需要將兩個(gè)頁(yè)面的內(nèi)容合并到一個(gè)item里面,這時(shí)候就需要在yield scrapy.Request的同時(shí),傳遞一些參數(shù)到一下頁(yè)面中。這時(shí)候可以這樣操作。

request=scrapy.Request(houseurl,method='GET',callback=self.showhousedetail)request.meta['biid']=biidyield requestdef showhousedetail(self,response):house=HouseItem()house['bulidingid']=response.meta['biid']

Items

爬取的主要目標(biāo)就是從非結(jié)構(gòu)性的數(shù)據(jù)源提取結(jié)構(gòu)性數(shù)據(jù),例如網(wǎng)頁(yè)。 Scrapy spider可以以python的dict來(lái)返回提取的數(shù)據(jù).雖然dict很方便,并且用起來(lái)也熟悉,但是其缺少結(jié)構(gòu)性,容易打錯(cuò)字段的名字或者返回不一致的數(shù)據(jù),尤其在具有多個(gè)spider的大項(xiàng)目中。。
為了定義常用的輸出數(shù)據(jù),Scrapy提供了Item 類(lèi)。 Item 對(duì)象是種簡(jiǎn)單的容器,保存了爬取到得數(shù)據(jù)。 其提供了 類(lèi)似于詞典(dictionary-like)的API以及用于聲明可用字段的簡(jiǎn)單語(yǔ)法。
聲明Item
Item使用簡(jiǎn)單的class定義語(yǔ)法以及 Field 對(duì)象來(lái)聲明。例如:

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

Item Pipeline

當(dāng)Item在Spider中被收集之后,它將會(huì)被傳遞到Item Pipeline,一些組件會(huì)按照一定的順序執(zhí)行對(duì)Item的處理。

每個(gè)item pipeline組件(有時(shí)稱之為“Item Pipeline”)是實(shí)現(xiàn)了簡(jiǎn)單方法的Python類(lèi)。他們接收到Item并通過(guò)它執(zhí)行一些行為,同時(shí)也決定此Item是否繼續(xù)通過(guò)pipeline,或是被丟棄而不再進(jìn)行處理。

編寫(xiě)你自己的item pipeline

編寫(xiě)你自己的item pipeline很簡(jiǎn)單,每個(gè)item pipiline組件是一個(gè)獨(dú)立的Python類(lèi),同時(shí)必須實(shí)現(xiàn)以下方法:

pipeline區(qū)分傳來(lái)Items

各個(gè)頁(yè)面都會(huì)封裝items并將item傳遞給pipelines來(lái)處理,而pipelines接收的入口只有一個(gè)就是

def process_item(self, item, spider)函數(shù)

spider 對(duì)應(yīng)相應(yīng)的爬蟲(chóng),調(diào)用spider.name也可區(qū)分來(lái)自不同爬蟲(chóng)的item

def process_item(self, item, spider):if str(type(item))=="<class 'rishome.items.RishomeItem'>":self.saverishome(item)if str(type(item))=="<class 'rishome.items.BulidingItem'>":self.savebuliding(item)if str(type(item))=="<class 'rishome.items.HouseItem'>":self.savehouse(item)return item # 必須實(shí)現(xiàn)返回

spider 對(duì)應(yīng)相應(yīng)的爬蟲(chóng),調(diào)用spider.name也可區(qū)分來(lái)自不同爬蟲(chóng)的item

def process_item(self, item, spider):if spider.name == "XXXX":pass
啟用一個(gè)Item Pipeline組件

為了啟用一個(gè)Item Pipeline組件,你必須將它的類(lèi)添加到ITEM_PIPELINES配置,就像下面這個(gè)例子:

ITEM_PIPELINES = {'myproject.pipelines.PricePipeline': 300,'myproject.pipelines.JsonWriterPipeline': 800, }

分配給每個(gè)類(lèi)的整型值,確定了他們運(yùn)行的順序,item按數(shù)字從低到高的順序,通過(guò)pipeline,通常將這些數(shù)字定義在0-1000范圍內(nèi)。

下載及處理文件和圖片

Scrapy為下載item中包含的文件(比如在爬取到產(chǎn)品時(shí),同時(shí)也想保存對(duì)應(yīng)的圖片)提供了一個(gè)可重用的item pipelines . 這些pipeline有些共同的方法和結(jié)構(gòu)(我們稱之為media pipeline)。一般來(lái)說(shuō)你會(huì)使用Files Pipeline或者 Images Pipeline.

使用Files Pipeline

當(dāng)使用 FilesPipeline ,典型的工作流程如下所示:

  • 在一個(gè)爬蟲(chóng)里,你抓取一個(gè)項(xiàng)目,把其中圖片的URL放入 file_urls組內(nèi)。

  • 項(xiàng)目從爬蟲(chóng)內(nèi)返回,進(jìn)入項(xiàng)目管道。

  • 當(dāng)項(xiàng)目進(jìn)入 FilesPipeline,file_urls組內(nèi)的URLs將被Scrapy的調(diào)度器和下載器(這意味著調(diào)度器和下載器的中間件可以復(fù)用)安排下載,當(dāng)優(yōu)先級(jí)更高,會(huì)在其他頁(yè)面被抓取前處理。項(xiàng)目會(huì)在這個(gè)特定的管道階段保持“l(fā)ocker”的狀態(tài),直到完成文件的下載(或者由于某些原因未完成下載)。

  • 當(dāng)文件下載完后,另一個(gè)字段(files)將被更新到結(jié)構(gòu)中。這個(gè)組將包含一個(gè)字典列表,其中包括下載文件的信息,比如下載路徑、源抓取地址(從file_urls組獲得)和圖片的校驗(yàn)碼(checksum)。 files列表中的文件順序?qū)⒑驮?file_urls組保持一致。如果某個(gè)圖片下載失敗,將會(huì)記錄下錯(cuò)誤信息,圖片也不會(huì)出現(xiàn)在 files 組中。

    import scrapyclass MyItem(scrapy.Item):# ... other item fields ...image_urls = scrapy.Field()images = scrapy.Field()
  • 在配置文件 settings.py中配置FILES_STORE,這個(gè)配置用來(lái)設(shè)置文件下載下來(lái)的路徑。

  • 啟動(dòng)pipeline,
    對(duì)于 Files Pipeline, 使用:

    ITEM_PIPELINES = {'scrapy.pipeline.files.FilesPipeline': 1}

    對(duì)于 Images Pipeline, 使用:

    ITEM_PIPELINES = {'scrapy.pipeline.images.ImagesPipeline': 1}

    接著IMAGES_STORE設(shè)置為一個(gè)有效的文件夾,用來(lái)存儲(chǔ)下載的圖片。 否則管道將保持禁用狀態(tài),即使你在ITEM_PIPELINES 設(shè)置中添加了它。
    對(duì)于Files Pipeline, 設(shè)置 FILES_STORE

    FILES_STORE = '/path/to/valid/dir'

    對(duì)于Images Pipeline, 設(shè)置 IMAGES_STORE

    IMAGES_STORE = '/path/to/valid/dir'
  • 其中:

    • <IMAGES_STORE> 是定義在IMAGES_STORE 設(shè)置里的文件夾
    • full是用來(lái)區(qū)分圖片和縮略圖(如果使用的話)的一個(gè)子文件夾。詳情參見(jiàn) 針對(duì)圖片生成縮略圖.

    1 傳統(tǒng)的Scrapy框架圖片下載方式

  • 創(chuàng)建項(xiàng)目:

  • 改寫(xiě)settings.py

    • 不遵守robots協(xié)議

      # Obey robots.txt rules ROBOTSTXT_OBEY = False
    • 設(shè)置請(qǐng)求頭

      # Override the default request headers: DEFAULT_REQUEST_HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36' }
  • 開(kāi)啟pipelinesITEM_PIPELINES = {'bmw.pipelines.BmwPipeline': 300, }
  • 改寫(xiě)items.py

    import scrapyclass BmwItem(scrapy.Item):category = scrapy.Field()image_urls = scrapy.Field()images = scrapy.Field()
  • 改寫(xiě)bmw5.py

    # -*- coding: utf-8 -*- import scrapy from bmw.items import BmwItemclass Bmw5Spider(scrapy.Spider):name = 'bmw5'allowed_domains = ['car.autohome.com.cn']start_urls = ['https://car.autohome.com.cn/pic/series/65.html']def parse(self, response):# SelectorList -> listuiboxs = response.xpath("//div[@class='uibox']")[1:]for uibox in uiboxs:category = uibox.xpath(".//div[@class='uibox-title']/a/text()").get()urls = uibox.xpath(".//ul/li/a/img/@src").getall()# for url in urls:# url = response.urljoin(url)# print(url)urls = list(map(lambda url:response.urljoin(url),urls))item = BmwItem(category=category,image_urls=urls)yield item
  • 改寫(xiě)pipelines.py

    # -*- coding: utf-8 -*-# Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html import os from urllib import request#導(dǎo)入兩個(gè)庫(kù) from scrapy.pipelines.images import ImagesPipeline from bmw import settingsclass BmwPipeline(object):def __init__(self):self.path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')if not os.path.exists(self.path):os.mkdir(self.path)def process_item(self, item, spider):category = item['category']urls = item['urls']category_path = os.path.join(self.path,category)if not os.path.exists(category_path):os.mkdir(category_path)for url in urls:image_name = url.split('_')[-1]request.urlretrieve(url,os.path.join(category_path,image_name))return item
  • 測(cè)試py

    from scrapy import cmdline cmdline.execute('scrapy crawl bmw5'.split())
  • Scrapy框架提供了兩個(gè)中間件、下載文件的Files pipeline 和下載圖片的Image pipeline

    下載文件的Files pipeline

    使用步驟:

  • 定義好一個(gè)item,然后定義兩個(gè)屬性file_urls 和 files , file_urls是用來(lái)存儲(chǔ)需要下載的文件的url鏈接,列表類(lèi)型

  • 當(dāng)文件下載完成后,會(huì)把文件下載的相關(guān)信息存儲(chǔ)到item的files屬性中。例如:下載路徑,下載url 和文件的效驗(yàn)碼

  • 再配置文件settings.py中配置FILES_STORE,指定文件下載路徑

  • 啟動(dòng)pipeline,在ITEM_PIPELINES中設(shè)置scrapy.pipelines.files.FilesPipeline :1

  • 下載圖片的Images Pipeline

    使用步驟:

  • 定義好一個(gè)item,然后定義兩個(gè)屬性image_urls和 images,image_urls是用來(lái)存儲(chǔ)需要下載的文件的url鏈接,列表類(lèi)型

  • 當(dāng)文件下載完成后,會(huì)把文件下載的相關(guān)信息存儲(chǔ)到item的images屬性中。例如:下載路徑,下載url 和文件的效驗(yàn)碼

  • 再配置文件settings.py中配置IMAGES_STORE,指定文件下載路徑

  • 啟動(dòng)pipeline,在ITEM_PIPELINES中設(shè)置scrapy.pipelines.images.ImagesPipeline :1

  • 使用Images_pipeline進(jìn)行圖片下載(還是以汽車(chē)之家圖片為例)
  • 改寫(xiě)settings.py
    開(kāi)啟自己定義的中間件

    ITEM_PIPELINES = {# 'bmw.pipelines.BmwPipeline': 300,#不分組情況下使用的pipeline'scrapy.pipelines.images.ImagesPipeline': 1 }

    配置IMAGES_STORE,指定文件下載路徑

    # 圖片下載的路徑,供images pipelines使用 IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')
  • 改寫(xiě)pipelines.py

    import os from urllib import request#導(dǎo)入兩個(gè)庫(kù) from scrapy.pipelines.images import ImagesPipeline from bmw import settingsclass BmwPipeline(object):def __init__(self):self.path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')if not os.path.exists(self.path):os.mkdir(self.path)def process_item(self, item, spider):category = item['category']urls = item['urls']category_path = os.path.join(self.path,category)if not os.path.exists(category_path):os.mkdir(category_path)for url in urls:image_name = url.split('_')[-1]request.urlretrieve(url,os.path.join(category_path,image_name))return item
  • 以這種方法下載的圖片,默認(rèn)下載到full文件下,能夠根據(jù)獲取的信息將圖片進(jìn)行分類(lèi)。

    優(yōu)化上述的方法
  • 改寫(xiě)pipelines.py

    # -*- coding: utf-8 -*-# Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html import os from urllib import request#導(dǎo)入ImagesPipeline from scrapy.pipelines.images import ImagesPipeline#導(dǎo)入settings 引用參數(shù)settings.IMAGES_STORE from bmw import settingsclass BmwPipeline(object):def __init__(self):self.path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')if not os.path.exists(self.path):os.mkdir(self.path)def process_item(self, item, spider):category = item['category']urls = item['urls']category_path = os.path.join(self.path,category)if not os.path.exists(category_path):os.mkdir(category_path)for url in urls:image_name = url.split('_')[-1]request.urlretrieve(url,os.path.join(category_path,image_name))return item#發(fā)送下載圖片的請(qǐng)求 '''def get_media_requests(self, item, info):return [Request(x) for x in item.get(self.images_urls_field, [])] '''# 更改路徑,自定義類(lèi) 繼承ImagesPipeline class BMWImagesPipeline(ImagesPipeline):def get_media_requests(self, item, info):# 這個(gè)方法是在發(fā)送下載請(qǐng)求之前調(diào)用。# 其實(shí)這個(gè)方法本身就是去發(fā)送下載請(qǐng)求的#調(diào)用父類(lèi)的get_media_requests() 方法request_objs = super(BMWImagesPipeline, self).get_media_requests(item,info)for request_obj in request_objs:request_obj.item = itemreturn request_objs#重寫(xiě)file_path 方法def file_path(self, request, response=None, info=None):# 這個(gè)方法是在圖片將要被存儲(chǔ)的時(shí)候調(diào)用,來(lái)獲取這個(gè)圖片存儲(chǔ)的路徑path = super(BMWImagesPipeline, self).file_path(request,response,info)# path = 'full/%s.jpg' 默認(rèn)存儲(chǔ)的文件路徑category = request.item.get('category') #得到分類(lèi)images_store = settings.IMAGES_STORE #存儲(chǔ)的文件路徑category_path = os.path.join(images_store,category) #分類(lèi)存儲(chǔ)的文件路徑#文件夾是否存在,不存在建立相應(yīng)分類(lèi)的文件夾if not os.path.exists(category_path):os.mkdir(category_path)#得到文件的名字image_name = path.replace("full/","")#文件的絕對(duì)路徑image_path = os.path.join(category_path,image_name)return image_path
  • 改寫(xiě)settings.py

    ITEM_PIPELINES = {# 'bmw.pipelines.BmwPipeline': 300,#不分組情況下使用的pipeline#'scrapy.pipelines.images.ImagesPipeline': 1#分組情況下使用自己定義的pipeline'bmw.pipelines.BMWImagesPipeline': 1 }
  • 在自定義ImagePipeline代碼中,作為重要的是要重載get_media_requests(self, item, info)和item_completed(self, results, item, info)這兩個(gè)函數(shù)。

    def file_path(self, request, response=None, info=None):image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()return 'full/%s.jpg' % (image_guid)def get_media_requests(self, item, info):return [Request(x) for x in item.get(self.images_urls_field, [])]#Request返回中 何以傳入其它的參數(shù),例如參數(shù)含有meta,def item_completed(self, results, item, info):if isinstance(item, dict) or self.images_result_field in item.fields:item[self.images_result_field] = [x for ok, x in results if ok]return item
    • get_media_requests()。它的第一個(gè)參數(shù)item是爬取生成的Item對(duì)象。我們將它的url字段取出來(lái),然后直接生成Request對(duì)象。此Request加入到調(diào)度隊(duì)列,等待被調(diào)度,執(zhí)行下載。
    • file_path()。它的第一個(gè)參數(shù)request就是當(dāng)前下載對(duì)應(yīng)的Request對(duì)象。這個(gè)方法用來(lái)返回保存的文件名,直接將圖片鏈接的最后一部分當(dāng)作文件名即可。它利用split()函數(shù)分割鏈接并提取最后一部分,返回結(jié)果。這樣此圖片下載之后保存的名稱就是該函數(shù)返回的文件名。
    • item_completed(),它是當(dāng)單個(gè)Item完成下載時(shí)的處理方法。因?yàn)椴⒉皇敲繌垐D片都會(huì)下載成功,所以我們需要分析下載結(jié)果并剔除下載失敗的圖片。如果某張圖片下載失敗,那么我們就不需保存此Item到數(shù)據(jù)庫(kù)。該方法的第一個(gè)參數(shù)results就是該Item對(duì)應(yīng)的下載結(jié)果,它是一個(gè)列表形式,列表每一個(gè)元素是一個(gè)元組,其中包含了下載成功或失敗的信息。這里我們遍歷下載結(jié)果找出所有成功的下載列表。如果列表為空,那么該Item對(duì)應(yīng)的圖片下載失敗,隨即拋出異常DropItem,該Item忽略。否則返回該Item,說(shuō)明此Item有效。

    get_media_requests用于解析item中image_urls中指定的url進(jìn)行爬取,可以通過(guò)get_media_requests為每個(gè)url生成一個(gè)Request。如:

    class ImagePipeline(ImagesPipeline):def get_media_requests(self, item, info):for image_url in item['image_urls']:yield scrapy.Request(image_url, meta={"image_name": item['image_name']})def file_path(self, request, response=None, info=None):file_name = request.meta['image_name'].strip().replace('\r\n\t\t', r'') + ".jpg"file_name=file_name.replace('/','_')return file_name

    總結(jié)

    以上是生活随笔為你收集整理的crawler(七):Scrapy的Request和Response、Files Pipeline、Images Pipeline的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。