Scrapy入門教程

1、查看python當前工作目錄

import os
>>>os.getcwd()

2、更改當前工作目錄

os.chdir('要設置的目錄')//同樣要導入import模塊

第一個Scrapy項目:

1、創建項目:

進入您打算存儲代碼的目錄中,運行下列命令:

scrapy startproject tutorial

該命令將會創建包含下列目錄的tutorial目錄:

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

這些文件分別是:

  • scrapy.cfg:項目的配置文件。
  • tutorial/:該項目的python模塊。之後您將在此加入代碼。
  • tutorial/items.py:項目中的item文件。
  • tutorial/pipelines.py:項目中的pipelines文件。
  • tutorial/settings.py:項目的設置文件。
  • tutorial/spiders/:放置spider代碼的目錄。

2、定義Item
Item是保存爬取道德數據的容器,使用方法和python字典類似,並且提供了額外保護機制來避免拼寫錯誤導致的未定義字段錯誤。
類似在ORM中做的一樣,你可以通過創建一個scrapy.Item 類,並且定義類型爲scrapy.Field 的類屬性來定義一個Item。
首先根據需要從dmoz.org獲取到的數據對item進行建模。我們需要從dmoz中獲取名字,url,以及網站的描述。對此,在item中定義相應的字段。編輯第二個tutorial目錄中的items.py文件(添加下列代碼):

import scrapy

class  DmozItem(scrapy.Item):
        title=scrapy.Field()
    link=scrapy.Field()
    desc=scrapy.Field()

通過定義item,你可以很方便的使用scrapy的其他方法。而這些方法需要知道你的item的定義。

3、編寫第一個爬蟲
Spider是用戶編寫用於從單個網站(或者一些網站)爬取數據的類。

其包含了一個用於下載的初始URL,如何跟進網頁中的鏈接以及如何分析頁面中的內容,提取生成item的方法。

爲了創建一個Spider,你必須繼承scrapy.Spider類,且定義以下三個屬性:

  • name:用於區別Spider。該名字必須是唯一的,你不可以爲不同的Spider設定相同的名字。
  • strat_urls:包含了Spider在啓動時進行爬取的url列表。因此,第一個被獲取到頁面將是其中之一。後續的URL則從初始的URL獲取到的數據中提取。
  • parse():是spider的一個方法。被調用時,每個初始URL完成下載後生成的Response對象將會作爲唯一的參數傳遞給該函數,該方法負責解析返回的數據(response data),提取數據(生成item)以及需要進一步處理的URL的Request對象。
    以下爲我們的第一個Spider代碼,保存在tutorial/tutorial/spiders目錄下的dmoz_spider.py文件中:
from scrapy.spider import Spider

class DmozSpider(Spider):
    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]
        with open(filename, 'wb') as f:
            f.write(response.body)

4、爬取
進入項目的根目錄,執行下列命令啓動spider:

scrapy crawl dmoz

crawl dmoz啓動用於爬取dmoz.org的spider,你將得到類似的輸出:

可以看到,有兩條輸出的log中包含定義在start_urls中的初始URL,並且與spider中是一一對應的。在log中可以看到其沒有指向其他頁面(referer:None)。

除此之外,就像我們在parse方法中指定的那樣,有兩個包含url所對應的內容的文件被創建了:Book和Resources。

剛剛發生了什麼?
scrapy爲Spider的start_urls屬性中的每個URL創建了scrapy.Request對象,並將parse方法作爲回調函數(callback)賦值給了Request。
Request對象經過調度,執行生成scrapy.http.Request對象並送回給spider的parse()方法。

5、提取Item
Selector選擇器簡介
從網頁中提取數據有很多方法。Scrapy使用了一種基於XPath和CSS表達式機制:Scrapy Selectors。關於selector和其他提取機制的信息請參考Selector文檔。
這裏給出XPath表達式的例子及對應的含義:

  • /html/head/title:選擇HTML文檔中< head >標籤內的< title >元素。
  • /html/head/title/text():選擇上面提到的< title >元素的文字。
  • //td:選擇所有的< td >元素。
  • //div[@class=”mine”]:選擇所有具有class=”mine”屬性的div元素。

上面僅僅是幾個簡單的XPath例子,XPath實際上要比這遠遠強大的多。如果你想了解的更多,可以參考這篇XPath教程

爲了配合XPath,Scrapy除了提供了Selector之外,還提供了方法來避免每次從response中提取數據時生成selector的麻煩。

Seletor有四個基本的方法(相應的方法可以看到詳細的API文檔):

  • xpath():傳入xpath表達式,返回該表達式所對應的所有節點的selector list列表。
  • css():傳入CSS表達式,返回該表達式所對應的所有節點的selector list列表。
  • extract():序列化該節點爲unicode字符串並返回list。
  • re():根據傳入的正則表達式對數據進行提取,返回unicode字符串list列表。

在Shell中嘗試Selector選擇器
爲了介紹Selector的使用方法,接下來我們將要使用內置的Scrapy shell。Scrapy Shell需要你預裝好IPython(一個擴展的Python終端)。

你需要進入項目的根目錄,執行下列命令來啓動shell:

scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"

注意:當你在終端運行Scrapy時,請一定記得給url地址加上引號,否則包含參數的url(例如&字符)會導致Scrapy運行失敗。

shell輸出類似:

當shell載入後,你將得到一個包含response數據的本地response變量。輸入response.body將輸出response的包體,輸出response.headers可以看到response的包頭。
更爲重要的是,當輸入response.selector時,你將獲取到一個可以用於查詢返回數據的selector(選擇器),以及映射到response.selector.xpath()、response.selector.css()的快捷方法(shortcut):response.xpath()和response.css()。

同時,shell根據response提前初始化了變量sel。該selector根據response的類型自動選擇最合適的分析規則(XML vs HTML)。

讓我們來試試:

提取數據
現在,我們來嘗試從頁面中提取有用的數據。
你可以在終端中輸入response.body來觀察HTML源碼並確定合適的XPath表達式。不過,這任務非常無聊且不易。你可以考慮使用Firefox的Firebug擴展來使得工作更爲輕鬆。
在查看了網頁的源碼後,你會發現網站的信息是被包含在第二個< ul >元素中。

我們可以通過這段代碼選擇該頁面中網站列表裏所有< li >元素:

sel.xpath('//ul/li')

網站的描述:

sel.xpath('//ul/li/text()').extract()

網站的標題:

sel.xpath('//ul/li/a/text()').extract()

以及網站的鏈接:

sel.xpath('//ul/li/a/@href').extract()

之前提到過,每個.xpath()調用返回selector組成的list,因此我們可以拼接更多的.xpath()來進一步獲取某個節點。我們將在下邊使用這樣的特性:

for sel in response.xpath('//ul/li'):
    title = sel.xpath('a/text()').extract()
    link = sel.xpath('a/@href').extract()
    desc = sel.xpath('text()').extract()
    print title, link, desc

在我們的spider中加入這段代碼:

from scrapy.spider import Spider

class DmozSpider(Spider):
    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):  
        for sel in response.xpath('//ul/li'):
            title = sel.xpath('a/text()').extract()
            link = sel.xpath('a/@href').extract()
            desc = sel.xpath('text()').extract()
            print title, link, desc

現在嘗試再次爬取dmoz.org,你將看到爬取到的網站信息被成功輸出:

scrapy crawl dmoz

使用item
Item對象是自定義的python字典。你可以使用標準的字典語法來獲取到其每個字段的值。(字段即是我們之前用Field賦值的屬性):

>>>item = DmozItem()
>>>item['title']= 'Example title'
>>>item['title']
'Example title'

一般來說,Spider會將爬取到的數據以Item對象返回。所以爲了將爬取的數據返回,我們最終的代碼是:

from scrapy.spider import Spider

class DmozSpider(Spider):
    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):  
        for sel in response.xpath('//ul/li'):
            item = DmozItem()
            item['title'] = sel.xpath('a/text()').extract()
            item['link'] = sel.xpath('a/@href').extract()
            item['desc'] = sel.xpath('text()').extract()
            yield item

現在對dmoz.org進行爬取將會產生DmozItem對象:

保存爬取到的數據
最簡單存儲爬取的數據的方式是使用Feed exports:

scrapy crawl dmoz -o items.json

該命令將採用JSON格式對爬取的數據進行序列化,生成items.json文件。

在類似本篇教程中這樣小規模的項目中,這種存儲方式已經足夠。如果需要對爬取到的item做更多更爲複雜的操作,你可以編寫Item Pipeline。類似於我們在創建項目時對Item做的,用於你編寫自己的tutorial/pipeline.py也被創建。不過如果你僅僅想要保存item,你不需要實現任何的pipeline。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章