- 精通Scrapy網絡爬蟲
- 劉碩
- 1022字
- 2020-11-28 14:59:39
3.1 Selector對象
從頁面中提取數據的核心技術是HTTP文本解析,在Python中常用以下模塊處理此類問題:
● BeautifulSoup
BeautifulSoup是非常流行的HTTP解析庫,API簡潔易用,但解析速度較慢。
● lxml
lxml是一套由C語言編寫的xml解析庫(libxml2),解析速度更快,API相對復雜。
Scrapy綜合上述兩者優點實現了Selector類,它是基于lxml庫構建的,并簡化了API接口。在Scrapy中使用Selector對象提取頁面中的數據,使用時先通過XPath或CSS選擇器選中頁面中要提取的數據,然后進行提取。
下面詳細介紹Selector對象的使用。
3.1.1 創建對象
Selector類的實現位于scrapy.selector模塊,創建Selector對象時,可將頁面的HTML文檔字符串傳遞給Selector構造器方法的text參數:
>>> from scrapy.selector import Selector >>> text = ''' ... <html> ... <body> ... <h1>Hello World</h1> ... <h1>Hello Scrapy</h1> ... <b>Hello python</b> ... <ul> ... <li>C++</li> ... <li>Java</li> ... <li>Python</li> ... </ul> ... </body> ... </html> ... ''' ... >>> selector = Selector(text=text) <Selector xpath=None data='<html>\n <body>\n <h1>He'>
也可以使用一個Response對象構造Selector對象,將其傳遞給Selector構造器方法的response參數:
>>> from scrapy.selector import Selector >>> from scrapy.http import HtmlResponse >>> body = ''' ... <html> ... <body> ... <h1>Hello World</h1> ... <h1>Hello Scrapy</h1> ... <b>Hello python</b> ... <ul> ... <li>C++</li> ... <li>Java</li> ... <li>Python</li> ... </ul> ... </body> ... </html> ... ''' ... >>> response = HtmlResponse(url='http://www.example.com', body=body, encoding='utf8') >>> selector = Selector(response=response) >>> selector <Selector xpath=None data='<html>\n <body>\n <h1>He'>
3.1.2 選中數據
調用Selector對象的xpath方法或css方法(傳入XPath或CSS選擇器表達式),可以選中文檔中的某個或某些部分:
>>>selector_list=selector.xpath('//h1') # 選中文檔中所有的<h1> >>>selector_list # 其中包含兩個<h1>對應的Selector對象 [<Selector xpath='.//h1' data='<h1>Hello World</h1>'>, <Selector xpath='.//h1' data='<h1>Hello Scrapy</h1>'>]
xpath和css方法返回一個SelectorList對象,其中包含每個被選中部分對應的Selector對象,SelectorList支持列表接口,可使用for語句迭代訪問其中的每一個Selector對象:
>>> for sel in selector_list: ... print(sel.xpath('./text()')) ... [<Selector xpath='./text()' data='Hello World'>] [<Selector xpath='./text()' data='Hello Scrapy'>]
SelectorList對象也有xpath和css方法,調用它們的行為是:以接收到的參數分別調用其中每一個Selector對象的xpath或css方法,并將所有結果收集到一個新的SelectorList對象返回給用戶。請看下面的示例:
>>> selector_list.xpath('./text()') [<Selector xpath='./text()' data='Hello World'>, <Selector xpath='./text()' data='Hello Scrapy'>] >>> selector.xpath('.//ul').css('li').xpath('./text()') [<Selector xpath='./text()' data='C++'>, <Selector xpath='./text()' data='Java'>, <Selector xpath='./text()' data='Python'>]
3.1.3 提取數據
調用Selector或SelectorLis對象的以下方法可將選中的內容提取:
● extract()
● re()
● extract_first() (SelectorList專有)
● re_first() (SelectorList專有)
首先來看extract方法,調用Selector對象的extract方法將返回選中內容的Unicode字符串:
>>> sl = selector.xpath('.//li') >>> sl [<Selector xpath='.//li' data='<li>C++</li>'>, <Selector xpath='.//li' data='<li>Java</li>'>, <Selector xpath='.//li' data='<li>Python</li>'>] >>> sl[0].extract() '<li>C++</li>' >>> sl = selector.xpath('.//li/text()') >>> sl [<Selector xpath='.//li/text()' data='C++'>, <Selector xpath='.//li/text()' data='Java'>, <Selector xpath='.//li/text()' data='Python'>] >>> sl[1].extract() 'Java'
與SelectorList對象的xpath和css方法類似,SelectorList對象的extract方法內部會調用其中每個Selector對象的extract方法,并把所有結果收集到一個列表返回給用戶:
>>> sl = selector.xpath('.//li/text()') >>> sl [<Selector xpath='.//li/text()' data='C++'>, <Selector xpath='.//li/text()' data='Java'>, <Selector xpath='.//li/text()' data='Python'>] >>> sl.extract() ['C++', 'Java', 'Python']
SelectorList對象還有一個extract_first方法,該方法返回其中第一個Selector對象調用extract方法的結果。通常,在SelectorList對象中只包含一個Selector對象時調用該方法,直接提取出Unicode字符串而不是列表:
>>> sl = selector.xpath('.//b') >>> sl [<Selector xpath='.//b' data='<b>Hello Python</b>'>] >>> sl.extract() ['<b>Hello Python</b>'] >>> sl.extract_first() '<b>Hello Python</b>'
有些時候,我們想使用正則表達式提取選中內容中的某部分,可以使用re方法(兩個對象都有該方法):
>>> text = ''' ... <ul> ... <li>Python學習手冊 <b>價格: 99.00元</b></li> ... <li>Python核心編程 <b>價格: 88.00元</b></li> ... <li>Python基礎教程 <b>價格: 80.00元</b></li> ... </ul> ... ''' ... >>> selector = Selector(text=text) >>> selector.xpath('.//li/b/text()') [<Selector xpath='.//li/b/text()' data=’價格: 99.00元’>, <Selector xpath='.//li/b/text()' data=’價格: 88.00元’>, <Selector xpath='.//li/b/text()' data=’價格: 80.00元’>] >>> selector.xpath('.//li/b/text()').extract() [’價格: 99.00元’, ’價格: 88.00元’, ’價格: 80.00元’] >>> selector.xpath('.//li/b/text()').re('\d+\.\d+') #只提取價格的數字部分 ['99.00', '88.00', '80.00']
SelectorList對象的re_first方法同樣返回其中的第一個Selector對象調用re方法的結果:
>>> selector.xpath('.//li/b/text()').re_first('\d+\.\d+') '99.00'
- Python概率統計
- Blender 3D Incredible Machines
- 征服RIA
- Monitoring Elasticsearch
- STM32F0實戰:基于HAL庫開發
- 從Excel到Python:用Python輕松處理Excel數據(第2版)
- 軟件測試技術指南
- Learning SciPy for Numerical and Scientific Computing(Second Edition)
- C++ Fundamentals
- Scala編程(第5版)
- 零代碼實戰:企業級應用搭建與案例詳解
- Python 3 數據分析與機器學習實戰
- 軟件工程基礎與實訓教程
- 工業機器人離線編程
- Vue.js 3應用開發與核心源碼解析