scrapy Selector用法及xpath語法


准備工作

html示例:

<?xml version="1.0" encoding="UTF-8"?>
<html
<head>
    <title>text</title>
</head>

<body>

<div class="cdiv">
    <p class="cp1 section">test p1 <span>next p1</span></p>
    <ul>
        <li id="0">1</li>
        <li id="1">2</li>
        <li id="2">3</li>
    </ul>
</div>

<div class="cdiv1">
     <p class="cp2">test p2 <span>next p2</span></p>
     <ul>
        <li id="3">4</li>
        <li id="4">5</li>
        <li id="5">6</li>
    </ul>
</div>

<p class="item">test in p </p>

<li id="6" class="item cli-1">7</li>
<li id="7" class="item cli-2">8</li>


</body>

</html>

把該示例保存到test.html中.

創建python文件,輸入代碼

from scrapy.selector import Selector

doc = ''
with open('./test.html', 'r') as f:
    doc = f.read()

sel = Selector(text=doc)

后面所有的示例代碼都會添加到這個文件中

Selector的主要方法

得到選中節點的字符串

get(): 得到選中節點列表中的第一個中節點, 並轉換成字符串返回。

getall(): 得到選中節點列表中的所有節點,並轉換成字符串返回。

示例:

#得到選中節點字符串
res = sel.css('.cdiv').xpath(".//li").get()
print(res)
res = sel.css('.cdiv').xpath(".//li").getall()
print(res)

結果:

<li id="0">1</li>
['<li id="0">1</li>', '<li id="1">2</li>', '<li id="2">3</li>']

用正則表達式匹配

re(regex): 用正則表達式匹配節點,並返回匹配的字符串。

示例:

res = sel.css('body .item').re(r'cli\-\d+')
print(res)

結果:

['cli-1', 'cli-2']

使用xpath表達式選擇節點

xpath(query): 使用xpath表達式選擇節點, 並返包含選中節點的Selector對象.

使用css選擇器選中節點

css(query): 使用css選擇器表達式選擇節點, 並返包含選中節點的Selector對象

xpath 語法

選擇所有的子節點

//{node}: 選擇根節點下所有標簽為{node}的子節點.

//{node}//{node1}: 選擇根節點下所有標簽為{node1}且父節點包含標簽{node}的節點

示例1:

res = sel.xpath("//li")
print(res)

結果:

[<Selector xpath='//li' data='<li id="0">1</li>'>, <Selector xpath='//li' data='<li id="1">2</li>'>, <Selector xpath='//li' data='<li id="2">3</li>'>, <Selector xpath='//li' data='<li id="3">4</li>'>, <Selector xpath='//li' data='<li id="4">5</li>'>, <Selector xpath='//li' data='<li id="5">6</li>'>, <Selector xpath='//li' data='<li id="6" class="item cli-1">7</li>'>, <Selector xpath='//li' data='<li id="7" class="item cli-2">8</li>'>]

示例2

res = sel.xpath("//ul//li")
print(res)

結果

[
<Selector xpath='//ul//li' data='<li>1</li>'>, 
<Selector xpath='//ul//li' data='<li>2</li>'>, 
<Selector xpath='//ul//li' data='<li>3</li>'>, 
<Selector xpath='//ul//li' data='<li>4</li>'>, 
<Selector xpath='//ul//li' data='<li>5</li>'>,
<Selector xpath='//ul//li' data='<li>6</li>'>
]

選擇直接子節點

{node}/{node1}: 選擇從{node}的直接子節點中選擇標簽為{node1}節點.

示例1:

res = sel.xpath("//body/li")
print(res)

結果:

[<Selector xpath='//body/li' data='<li id="6" class="item cli-1">7</li>'>, <Selector xpath='//body/li' data='<li id="7" class="item cli-2">8</li>'>]

從選擇的子節點列表中選擇第n個子節點

//{node}[n]: 先把兄弟節點聚合在一個list變成[list_1, list_2, ...], 然后從每個list中選擇第n個, 如果list的長度不足n個則跳過.

(//{node})[n]: 把所有選擇的節點放在一條list, 然后從這個list中選擇第n個

示例1:

res = sel.xpath("//li[1]")
print(res)
res = sel.xpath("//li[3]")
print(res)

結果:

[<Selector xpath='//li[1]' data='<li id="0">1</li>'>, <Selector xpath='//li[1]' data='<li id="3">4</li>'>, <Selector xpath='//li[1]' data='<li id="6" class="item cli-1">7</li>'>]
[<Selector xpath='//li[3]' data='<li id="2">3</li>'>, <Selector xpath='//li[3]' data='<li id="5">6</li>'>]

示例2

res = sel.xpath("(//li)[1]")
print(res)
res = sel.xpath("(//li)[3]")
print(res)

結果:

[<Selector xpath='(//li)[1]' data='<li>1</li>'>]
[<Selector xpath='(//li)[3]' data='<li>3</li>'>]

使用節點屬性作為選擇條件

{node}[@{attr}='{val}']: 選中節點必須有名字為{attr}的屬性, 且這個屬性的值等於{val}.

{node}[contains(@{attr}, '{val}']: 選中節點必須有名字為'{attr}'的屬性, 且這個屬性的值包含{val}.

示例1

res = sel.xpath("//p[@class='cp1']")
print(res)
res = sel.xpath("//p[@class='cp2']")
print(res)
res = sel.xpath("//p[contains(@class, 'cp1')]")
print(res)

結果

[]
[<Selector xpath="//p[@class='cp2']" data='<p class="cp2">test p2 <span>next p2<...'>]
[<Selector xpath="//p[contains(@class, 'cp1')]" data='<p class="cp1 section">test p1 <span>...'>]
[<Selector xpath="descendant-or-self::p[@class and contains(concat(' ', normalize-space(@class), ' '), ' cp1 ')]" data='<p class="cp1 section">test p1 <span>...'>]

在包含條件中, 如果使用'class'屬性, 可以用css選擇器簡化:

示例2:

res = sel.css("p.cp1")
print(res)

結果:

[<Selector xpath="descendant-or-self::p[@class and contains(concat(' ', normalize-space(@class), ' '), ' cp1 ')]" data='<p class="cp1 section">test p1 <span>...'>]

提取節點屬性的值

{node}/@{attr}: 提取選擇節的點中屬性名為{attr}的值.

示例1:

res = sel.xpath("//p/@class")
print(res)
print("\n")

結果

[<Selector xpath='//p/@class' data='cp1 section'>, <Selector xpath='//p/@class' data='cp2'>]

提取節點中的文本內容

{node}/text(): 提取當前選擇節點的文本內容, 不包括子節點的文本.

{node}//text(): 提取選擇節點的文本內容, 包括子節點的文本.

示例1:

res = sel.xpath("//p//text()")
print(res)
res = sel.xpath("//p/text()")
print(res)

結果:

[<Selector xpath='//p//text()' data='test p1 '>, <Selector xpath='//p//text()' data='next p1'>, <Selector xpath='//p//text()' data='test p2 '>, <Selector xpath='//p//text()' data='next p2'>]
[<Selector xpath='//p/text()' data='test p1 '>, <Selector xpath='//p/text()' data='test p2 '>]

在xpath表達式中使用變量

在xpath表達式中是${varname}定義變量, 類似於bash

示例1:

#使用變量$val
res = sel.xpath("//li[@id=$val]", val='1')
print(res)
res = sel.xpath("//li[@id=$val]", val='3')
print(res)
res = sel.xpath("//li[@id=$val]", val='6')
print(res)

結果:

[<Selector xpath='//li[@id=$val]' data='<li id="1">2</li>'>]
[<Selector xpath='//li[@id=$val]' data='<li id="3">4</li>'>]
[<Selector xpath='//li[@id=$val]' data='<li id="6" class="item cli-1">7</li>'>]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM