三分鐘學會Scrapy選擇器(selectors)
入門級爬蟲總體分為兩步:下載網頁、提取數據
提取數據是我們的終極目的,提取數據的方法很多。最原始的是正則表達式,即使正則表達式是那麼的不人性化,但是不可否認他的強大之處。當然在Python的世界裡,它允許你不會使用正則表達式,他給你提供了另一種十分簡潔的方法:lxml,它通過層層節點來提取數據。但是這彷彿沒有讓程序員們停下腳步來,不久更加便捷的BeautifulSoup誕生了,BeautifulSoup會把html拆解成對象處理,全篇轉成字典和數組進行處理,操作更加傻瓜。
帶來了更大的好處,必然會犧牲一些東西,BeautifulSoup在大大降低提取難度的時候也降低了提取的速度,而這個時候lxml(通過特定的XPath或CSS表達式來選擇HTML文件中的某個部分)開始逐漸被大部分希望速度和便捷度並存的程序員所接受。Scrapy就選擇了lxml作為它的選擇器的基礎,Scrapy選擇器構建於lxml上,這意味著它在速度和解析準確性上非常相似。
Scrapy的構造器是以文字或TextResponse構造的Selector實例,它會根據輸入的類型自動選擇最優化的分析方法,而你不需要去考慮裡面具體的實現方法。
Scrapy的選擇器功能強於lxml與BeautifulSoup,在自由度方面,也高於兩者,我們以http://blog.csdn.net為例,使用Scrapy選擇器提取內容。
1、使用.xpath()提取內容
2、使用.css()提取內容
主要內容都寫在代碼注釋中,請配合注釋、代碼以及輸出仔細閱讀,如果還對Scrapy的選擇器不太了解,可以仔細閱讀Scrapy的官方文檔。
下面使一些官方文檔給出的當你使用Scrapy中的選擇器XPath時候可能會有用的一些意見,這些建議是建立在ScrapingHub』s blog ,如果你對XPath還不熟悉,請仔細閱讀這篇文章:XPath tutorial.
3、有關於XPath的一些建議
1)使用.代替.//text()
因為.//text()返回的是一個節點集合(set),當一個節點集合(node-set)轉強制換成string的時候,它僅僅會返回集合中的第一個元素。
>>> from scrapy import Selectorn>>> sel = Selector(text=<a href="#">Click here to go to the <strong>Next Page</strong></a>)n>>> sel.xpath(//a//text()).extract() # take a peek at the node-setn[uClick here to go to the , uNext Page]n>>> sel.xpath("//a[contains(., Next Page)]").extract()n[u<a href="#">Click here to go to the <strong>Next Page</strong></a>]n
2)注意//node[1]和(//node)[1]的區別
這種問題,熟悉Python的人都應該知道。
- //node[1]選擇所有位於第一個子節點位置的node節點
- (//node)[1]選擇整個文檔中的node節點,並且返回每個node節點的第一個節點
3)使用class查找時優先考慮CSS
因為一個元素可能包含很多的CSS樣式,使用XPath中的class選擇法很複雜,而使用CSS看起來更加易讀。
>>> from scrapy import Selectorn>>> sel = Selector(text=<div class="hero shout"><time datetime="2014-07-23 19:00">Special date</time></div>)n>>> sel.css(.shout).xpath(./time/@datetime).extract()n[u2014-07-23 19:00]n
更多文章,關註:知乎專欄
推薦閱讀:
※敲敲級簡單的鑒別H圖片的小程序
※pandas操作——合併數據集
※如何優雅的「輪帶逛」初級篇——獲取單張圖片
※揣著Django做項目2:組隊