官术网_书友最值得收藏!

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'
主站蜘蛛池模板: 宁乡县| 河北省| 偏关县| 历史| 长葛市| 科技| 新安县| 隆德县| 广丰县| 建始县| 普安县| 张家港市| 都江堰市| 澎湖县| 嵊泗县| 枝江市| 遂昌县| 辉县市| 铜鼓县| 虞城县| 肃宁县| 普兰县| 金昌市| 文昌市| 响水县| 辽阳县| 金塔县| 来安县| 商洛市| 沂南县| 潞城市| 临武县| 明光市| 灵川县| 乌兰察布市| 衡东县| 静乐县| 雅江县| 阿勒泰市| 原阳县| 信阳市|