嗨,在上一篇文章中已經說明了Item Pipeline中process_item()的使用,接下來我們來看看其他的方法吧,除了process_item()為必要的,其它的像是open_spider(spider), close_spider(spider)皆為選用的:
open_spider(spider): 當spider被打開時啟用close_spider(spider): 當spider被關閉時啟用昨天,輸出成檔案之後可以發現若文章被刪除了標題就會為空值null(例如:{"push": 1, "title": null, "href": null, "date": "10/24", "author": "-"} 的一筆資料。)
那要怎麼去除被刪除的文章呢?
開啟pipelines.py檔案,在最上面增加:
from scrapy.exceptions import DropItem
為了確保輸出的資料內容不會為null,我們新增一個類別DeleteNullTitlePipeline來實做過濾空值資料,程式碼:
class DeleteNullTitlePipeline(object):
    def process_item(self, item, spider):
        title = item['title'] 
        if title:
            return item
        else:
            raise DropItem('found null title %s', item)
Pipeline接收到一篇文章時,便去判斷它是否為空值,若為空值則透過DropItem()這個處理例外的方法將Item去掉,若有值再回傳item。別忘了一個很重要的事情!
就是要啟用DeleteNullTitlePipeline,不然會發現怎麼執行結果都沒變。
settings.py檔案'myFirstScrapyProject.pipelines.DeleteNullTitlePipeline': 200,如下:ITEM_PIPELINES = {
'myFirstScrapyProject.pipelines.MyfirstscrapyprojectPipeline': 300,
'myFirstScrapyProject.pipelines.DeleteNullTitlePipeline': 200,
}
再執行程式碼:
scrapy crawl ptt -o ptt.json
若收到空值則會看到爬蟲的log出現警告:
[scrapy.core.scraper] WARNING: Dropped: ('found null title %s', {'author': '-', 'date': '10/23', 'href': None, 'push': None,'title': None})
{'author': '-', 'date': '10/23', 'href': None, 'push': None, 'title': None}
ptt.json應該會發現裡面沒有"title":null的資料了!現在說明如何過濾重複的資料:
DuplicatesTitlePipeline的類別。article的集合。class DuplicatesTitlePipeline(object):
    def __init__(self):
        self.article = set()
    def process_item(self, item, spider):
        title = item['title'] 
        if title in self.article:
            raise DropItem('duplicates title found %s', item)
        self.article.add(title)
        return(item)
最重要的當然是啟用DuplicatesTitlePipeline:
Pipeline新增'myFirstScrapyProject.pipelines.DuplicatesTitlePipeline': 211。ITEM_PIPELINES = {
   'myFirstScrapyProject.pipelines.MyfirstscrapyprojectPipeline': 300,
   'myFirstScrapyProject.pipelines.DeleteNullTitlePipeline': 200,
   'myFirstScrapyProject.pipelines.DuplicatesTitlePipeline': 400,
}
這樣就完成了!
PTT版,可能就不適合單用title來過濾重複,因為通常回文的標題都是一樣的,這樣會不小心把文章都過濾掉了,所以要確定好需求再去寫pipelines哦!今天說明了透過Pipeline過濾重複資料, 刪除不存在文章,接下來會說明如何將資料透過Pipeline存入不同的資料庫中。
今天就到這裡了,明天見啦!