python scrapy簡介

來源:互聯網
上載者:User
scrapy基礎

scrapy是用python寫的一個庫,使用它可以方便的抓取網頁。

首頁地址http://scrapy.org/

文檔 http://doc.scrapy.org/en/latest/index.html

安裝 sudo pip install scrapy

一個簡單的教程 http://doc.scrapy.org/en/latest/intro/tutorial.html

如果你對這些概念有瞭解,使用上面的教程會比較容易. 它們是json, xpath, Regex, 

產生項目

scrapy提供一個工具來產生項目,產生的項目中預置了一些檔案,使用者需要在這些檔案中添加自己的代碼。

開啟命令列,執行:scrapy startproject tutorial,產生的項目類似下面的結構

tutorial/    scrapy.cfg    tutorial/        __init__.py        items.py        pipelines.py        settings.py        spiders/            __init__.py            ...

scrapy.cfg是項目的設定檔

使用者自己寫的spider要放在spiders目錄下面,一個spider類似

from scrapy.spider import BaseSpiderclass DmozSpider(BaseSpider):    name = "dmoz"    allowed_domains = ["dmoz.org"]    start_urls = [        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"    ]    def parse(self, response):        filename = response.url.split("/")[-2]        open(filename, 'wb').write(response.body)

name屬性很重要,不同spider不能使用相同的name

start_urls是spider抓取網頁的起始點,可以包括多個url

parse方法是spider抓到一個網頁以後預設調用的callback,避免使用這個名字來定義自己的方法。

當spider拿到url的內容以後,會調用parse方法,並且傳遞一個response參數給它,response包含了抓到的網頁的內容,在parse方法裡,你可以從抓到的網頁裡面解析資料。上面的代碼只是簡單地把網頁內容儲存到檔案。

 

開始抓取

你可以開啟命令列,進入產生的項目根目錄tutorial/,執行 scrapy crawl dmoz, dmoz是spider的name。

 

解析網頁內容

scrapy提供了方便的辦法從網頁中解析資料,這需要使用到HtmlXPathSelector

from scrapy.spider import BaseSpiderfrom scrapy.selector import HtmlXPathSelectorclass DmozSpider(BaseSpider):    name = "dmoz"    allowed_domains = ["dmoz.org"]    start_urls = [        "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",        "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"    ]    def parse(self, response):        hxs = HtmlXPathSelector(response)        sites = hxs.select('//ul/li')        for site in sites:            title = site.select('a/text()').extract()            link = site.select('a/@href').extract()            desc = site.select('text()').extract()            print title, link, desc

HtmlXPathSelector使用了Xpath來解析資料

//ul/li表示選擇所有的ul標籤下的li標籤

a/@href表示選擇所有a標籤的href屬性

a/text()表示選擇a標籤文本

a[@href="abc"]表示選擇所有href屬性是abc的a標籤

我們可以把解析出來的資料儲存在一個scrapy可以使用的對象中,然後scrapy可以協助我們把這些對象儲存起來,而不用我們自己把這些資料存到檔案中。我們需要在items.py中添加一些類,這些類用來描述我們要儲存的資料

from scrapy.item import Item, Fieldclass DmozItem(Item):    title = Field()    link = Field()    desc = Field()

然後在spider的parse方法中,我們把解析出來的資料儲存在DomzItem對象中。

from scrapy.spider import BaseSpiderfrom scrapy.selector import HtmlXPathSelectorfrom tutorial.items import DmozItemclass DmozSpider(BaseSpider):   name = "dmoz"   allowed_domains = ["dmoz.org"]   start_urls = [       "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",       "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"   ]   def parse(self, response):       hxs = HtmlXPathSelector(response)       sites = hxs.select('//ul/li')       items = []       for site in sites:           item = DmozItem()           item['title'] = site.select('a/text()').extract()           item['link'] = site.select('a/@href').extract()           item['desc'] = site.select('text()').extract()           items.append(item)       return items

在命令列執行scrapy的時候,我們可以加兩個參數,讓scrapy把parse方法返回的items輸出到json檔案中

scrapy crawl dmoz -o items.json -t json

items.json會被放在項目的根目錄

 

讓scrapy自動抓取網頁上的所有連結

上面的樣本中scrapy只抓取了start_urls裡面的兩個url的內容,但是通常我們想實現的是scrapy自動探索一個網頁上的所有連結,然後再去抓取這些連結的內容。為了實現這一點我們可以在parse方法裡面提取我們需要的連結,然後構造一些Request對象,並且把他們返回,scrapy會自動的去抓取這些連結。代碼類似:

class MySpider(BaseSpider):    name = 'myspider'    start_urls = (        'http://example.com/page1',        'http://example.com/page2',        )    def parse(self, response):        # collect `item_urls`        for item_url in item_urls:            yield Request(url=item_url, callback=self.parse_item)    def parse_item(self, response):        item = MyItem()        # populate `item` fields        yield Request(url=item_details_url, meta={'item': item},            callback=self.parse_details)    def parse_details(self, response):        item = response.meta['item']        # populate more `item` fields        return item

parse是預設的callback, 它返回了一個Request列表,scrapy自動的根據這個列表抓取網頁,每當抓到一個網頁,就會調用parse_item,parse_item也會返回一個列表,scrapy又會根據這個列表去抓網頁,並且抓到後調用parse_details

為了讓這樣的工作更容易,scrapy提供了另一個spider基類,利用它我們可以方便的實現自動抓取連結. 我們要用到CrawlSpider

from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractorclass MininovaSpider(CrawlSpider):    name = 'mininova.org'    allowed_domains = ['mininova.org']    start_urls = ['http://www.mininova.org/today']    rules = [Rule(SgmlLinkExtractor(allow=['/tor/\d+'])),             Rule(SgmlLinkExtractor(allow=['/abc/\d+']), 'parse_torrent')]    def parse_torrent(self, response):        x = HtmlXPathSelector(response)        torrent = TorrentItem()        torrent['url'] = response.url        torrent['name'] = x.select("//h1/text()").extract()        torrent['description'] = x.select("//div[@id='description']").extract()        torrent['size'] = x.select("//div[@id='info-left']/p[2]/text()[2]").extract()        return torrent

相比BaseSpider,新的類多了一個rules屬性,這個屬性是一個列表,它可以包含多個Rule,每個Rule描述了哪些連結需要抓取,哪些不需要。這是Rule類的文檔http://doc.scrapy.org/en/latest/topics/spiders.html#scrapy.contrib.spiders.Rule

這些rule可以有callback,也可以沒有,當沒有callback的時候,scrapy簡單的follow所有這些連結.

 

pipelines.py的使用

在pipelines.py中我們可以添加一些類來過濾掉我們不想要的item,把item儲存到資料庫。

from scrapy.exceptions import DropItemclass FilterWordsPipeline(object):    """A pipeline for filtering out items which contain certain words in their    description"""    # put all words in lowercase    words_to_filter = ['politics', 'religion']    def process_item(self, item, spider):        for word in self.words_to_filter:            if word in unicode(item['description']).lower():                raise DropItem("Contains forbidden word: %s" % word)        else:            return item

如果item不符合要求,那麼就拋一個異常,這個item不會被輸出到json檔案中。

要使用pipelines,我們還需要修改settings.py

添加一行

ITEM_PIPELINES = ['dirbot.pipelines.FilterWordsPipeline']

現在執行scrapy crawl dmoz -o items.json -t json,不符合要求的item就被過濾掉了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.