python爬蟲的最佳實踐(九)--Scrapy的items和pipeline

不想當(dāng)將軍的士兵不是好士兵,同理,不想當(dāng)主程的程序員不是好程序員~

上一節(jié)我們講了Scrapy的初步用法,我們已經(jīng)學(xué)會了如何創(chuàng)建scrapy工程,如何編寫簡單的爬蟲。

本節(jié)目標

  • 學(xué)會Scrapy item的創(chuàng)建及使用
  • 使用Scrapy將抓取到的數(shù)據(jù)存入json
  • 使用Scrapy Pipeline做數(shù)據(jù)處理
  • 學(xué)會暫停工程與重新開始工程

代碼預(yù)覽

  • items.py
class TutorialItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass

class xianyuItem(scrapy.Item):
    title = scrapy.Field()
    url = scrapy.Field()
    pass
  • pipelines.py
import pymongo

class TutorialPipeline(object):
    def open_spider(self, spider):
        self.client = pymongo.MongoClient('localhost', 27017)
        self.test = self.client['test']
        self.testData = self.test['testData']
        pass

    def process_item(self, item, spider):
        data = {
            'title': item['title'],
            'url': item['url']
        }
        self.testData.insert_one(data)
        return item

    def close_spider(self, spider):
        pass
  • spider.py
#coding:utf-8
import scrapy
from bs4 import BeautifulSoup
from ..items import xianyuItem

class testSpider(scrapy.Spider):
    name = 'test'
    start_urls = ['http://tj.ganji.com/fang1/']

    def parse(self, response):
        print 'lalala'
        for title in response.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "js-title", " " ))]'):
            url = title.xpath('@href').extract()[0]
            if url.find('http')==-1:
                url = 'http://tj.ganji.com'+url
            yield scrapy.Request(url, self.detail)

    def detail(self, response):
        data = BeautifulSoup(response.body, 'lxml')
        title = data.select('div.content.clearfix > div.leftBox > div.col-cont.title-box > h1')
        item = xianyuItem()
        item['title'] = title[0].get_text()
        item['url'] = response.url
        return item
  • settings.py
ITEM_PIPELINES = {
   'tutorial.pipelines.TutorialPipeline': 300,
}

代碼剖析

今天的代碼由三部分主體構(gòu)成,首先來看items.py

class xianyuItem(scrapy.Item):
    title = scrapy.Field()
    url = scrapy.Field()
    pass

其實很好理解力,定義一個我們自己的item結(jié)構(gòu),里面有兩個field,一個是title用來存儲抓來的標題,一個是url用來存儲抓來的url,我們直接跳到使用部分。

看spider.py,首先:

from ..items import xianyuItem

這里需要注意的是,因為items.py和我們的spider.py并不在同級目錄,如果要import需要在前面加上..表示上級目錄,當(dāng)然也可以這樣

from tutorial.items import xianyuItem

但是這樣會在pycharm里面報錯,我個人不喜歡看到紅字~推薦用上面的方式。我們來看detail函數(shù):

def detail(self, response):
        data = BeautifulSoup(response.body, 'lxml')
        title = data.select('div.content.clearfix > div.leftBox > div.col-cont.title-box > h1')
        item = xianyuItem()
        item['title'] = title[0].get_text()
        item['url'] = response.url
        return item

我們先創(chuàng)建一個xianyuItem對象,然后給里面每個field賦值,最后return這個對象。這樣,item就會被pipeline抓到。接下來我們用命令把抓來的數(shù)據(jù)導(dǎo)入到j(luò)son文件中。進入tutorial項目跟目錄,執(zhí)行

scrapy crawl test -o test.json -t json

-o表示文件寫入目錄 -t 表示格式,執(zhí)行完后打開test.json結(jié)果如圖:


1.png

這樣就可以把數(shù)據(jù)存入json中,接下來我們看看pipelines.py

def open_spider(self, spider):
def process_item(self, item, spider):
def close_spider(self, spider):

三個函數(shù),第一個open_spider在spider開始的時候執(zhí)行,在這個函數(shù)中我們一般會連接數(shù)據(jù)庫,為數(shù)據(jù)存儲做準備,上面代碼中我連接了mongo數(shù)據(jù)庫。process_item函數(shù)在捕捉到item的時候執(zhí)行,一般我們會在這里做數(shù)據(jù)過濾并且把數(shù)據(jù)存入數(shù)據(jù)庫。close_spider在spider結(jié)束的時候執(zhí)行,一般用來斷開數(shù)據(jù)庫連接或者做數(shù)據(jù)收尾工作。

寫好pipeline之后我們需要到settings.py中開啟pipeline:

ITEM_PIPELINES = { 
  'tutorial.pipelines.TutorialPipeline': 300,
}

找到ITEM_PIPELINES 選項,把我們pipeline的路徑配置進去,后面的數(shù)字表示的是pipeline的執(zhí)行順序,我們可以寫多個pipeline用來過濾數(shù)據(jù)。執(zhí)行結(jié)果如下:

I)VX)ETO86N08}8USYSG8VW.png

至此,我們本次代碼解析完畢。你們應(yīng)該已經(jīng)會使用item和pipeline了吧。如果還有困惑可以去看官方文檔~

小技巧

當(dāng)我們一個爬蟲項目量非常大時候,我們可能不能一次執(zhí)行完畢,需要分好幾次執(zhí)行,這時候,我們只需要在啟動爬蟲的時候鍵入命令

scrapy crawl xxx -s JOBDIR=job1

這時候我們可以看到任務(wù)開始執(zhí)行了,當(dāng)我們想要暫停的時候按下ctrl+c。當(dāng)我們想要恢復(fù)的時候鍵入:

scrapy crawl xxx -s JOBDIR=job1

這樣就可以繼續(xù)執(zhí)行了~~
這樣,我們今天所有的目標都達成了,鼓掌~~

寫在最后

這一章我們學(xué)習(xí)了一些進階技巧,那么下一章我們還是Scrapy,下一章我們會講如何使用CrawlSpider做多網(wǎng)頁扒取,同時也會講一些小技巧,比如,如何動態(tài)更改User-Agent進行反扒,如何設(shè)置扒取間隔等等~

有興趣的同學(xué)可以加群498945822一起交流學(xué)習(xí)哦~~
發(fā)現(xiàn)問題的同學(xué)歡迎指正,直接說就行,不用留面子,博主臉皮厚!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容