【Scrapy】 selector 學習記錄三(Selector詳細介紹)

Selector的詳細介紹

class scrapy.selector.Selector(response = None,text = None,type = None)

selector 是對 response 的封裝,用來對選取其中的特定內容。css

下面是 Selector 的主要成員變量:html

  • response 一個HtmlResponse或者XmlResponse對象git

  • text 一個unicode字符串或者utf-8文本,當response爲空的時候纔有效。同時使用text和response是未定義行爲github

  • type 定義selector的類型,能夠是html、xml或None(default)正則表達式

    • 若是type爲None,那麼selector會根據response自動選擇最佳的type,若是定義了text那麼默認成html類型
    • response的類型肯定
    • xml:XmlResponse
    • html:HtmlResponse
    • html:其餘類型
    • 若是已經設定了type那麼強制使用設定好的type。

主要成員函數:

- xpath() 尋找匹配xpath query 的節點,並返回 SelectorList 的一個實例結果,單一化其全部元素。返回的列表元素也實現了 Selector 的接口。query 是包含XPATH查詢請求的字符串。
- css() 應用給定的CSS選擇器,返回 SelectorList 的一個實例。在後臺,經過 cssselect 庫和運行 .xpath() 方法,CSS查詢會被轉換爲XPath查詢。
- extract() 串行化並將匹配到的節點返回一個unicode字符串列表。 結尾是編碼內容的百分比
- reg(regex) 應用給定的regex,並返回匹配到的unicode字符串列表。regex 能夠是一個已編譯的正則表達式,也能夠是一個將被 re.compile(regex) 編譯爲正則表達式的字符串。
- register_namespaces(prefix, uri) 註冊給定的命名空間,其將在 Selector 中使用。 不註冊命名空間,你將沒法從非標準命名空間中選擇或提取數據。
- remove_namespaces() 移除全部的命名空間,容許使用少許的命名空間xpaths遍歷文檔
- __nonzero__() 若是選擇了任意的真實文檔,將返回 True ,不然返回 False 。 也就是說, Selector 的布爾值是經過它選擇的內容肯定的。

SelectorList對象

class scrapy.selector.SelectorList

SelectorList 類是內建 list 類的子類,提供了一些額外的方法。shell

- xpath(query) 對列表中的每一個元素調用 .xpath() 方法,返回結果爲另外一個單一化的     SelectorList
- css(query) 對列表中的各個元素調用 .css() 方法,返回結果爲另外一個單一化的 SelectorList
- extract() 對列表中的各個元素調用 .extract() 方法,返回結果爲單一化的unicode字符串列表
- re() 對列表中的各個元素調用 .re() 方法,返回結果爲單一化的unicode字符串列表
- __nonzero__() 列表非空則返回True,不然返回False

在XML響應上的選擇器樣例

假設已經有一個經過 XmlResponse 對象實例化的 Selector ,以下:scrapy

sel = Selector(xml_response)

選擇全部的 元素,返回SelectorList :函數

sel.xpath(「//product」)

從 Google Base XML feed 中提取全部的價錢,這須要註冊一個命名空間:性能

sel.register_namespace("g", "http://base.google.com/ns/1.0")
sel.xpath("//g:price").extract()

移除命名空間

在處理爬蟲項目時,能夠徹底去掉命名空間而僅僅處理元素名字,這樣在寫更多簡單/實用的XPath會方便不少。爲此能夠使用Selector.remove_namespaces()方法。google

以Github博客的atom訂閱來解釋這個狀況。

首先,咱們使用想爬取的url來打開shell:

scrapy shell https://github.com/blog.atom

一旦進入shell,咱們能夠嘗試選擇全部的 <link> 對象,能夠看到沒有結果(由於Atom XML命名空間混淆了這些節點):

>>> response.xpath("//link")
[]

但一旦咱們調用 **Selector.remove_namespaces() **方法,全部的節點均可以直接經過他們的名字來訪問:

>>> response.selector.remove_namespaces()
>>> response.xpath("//link")  
[<Selector xpath='//link' data=u'<link xmlns="http://www.w3.org/2005/Atom'>,
<Selector xpath='//link' data=u'<link xmlns="http://www.w3.org/2005/Atom'>,
...

若是你對爲何命名空間移除操做並不老是被調用,而須要手動調用有疑惑。這是由於存在以下兩個緣由,按照相關順序以下: 1. 移除命名空間須要迭代並修改文件的全部節點,而這對於Scrapy爬取的全部文檔操做須要必定的性能消耗 2. 會存在這樣的狀況,確實須要使用命名空間,但有些元素的名字與命名空間衝突。儘管這些狀況很是少見。

若是XPath沒有指定命名空間的話,那麼它的命名空間爲空。若是待解析XML文件含有默認命名空間的話,那麼你必須添加那個命名空間的前綴,而且把命名空間的URI添加到XmlNamespaceManager中,不然,你得不到任何查詢結果。

對於scrapy,這裏提供了register_namespaces(prefix, uri) 和 remove_namespaces()兩個函數來解決這個問題。

相關文章
相關標籤/搜索