准备工作
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 语法
选择所有的子节点
//: 选择根节点下所有标签为的子节点.
////: 选择根节点下所有标签为且父节点包含标签的节点
示例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>'> ]
选择直接子节点
/: 选择从的直接子节点中选择标签为节点.
示例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个子节点
//[n]: 先把兄弟节点聚合在一个list变成[list_1, list_2, ...], 然后从每个list中选择第n个, 如果list的长度不足n个则跳过.
(//)[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>'>]
使用节点属性作为选择条件
[@='']: 选中节点必须有名字为的属性, 且这个属性的值等于.
[contains(@, '']: 选中节点必须有名字为''的属性, 且这个属性的值包含.
示例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>...'>]
提取节点属性的值
/@: 提取选择节的点中属性名为的值.
示例1:
res = sel.xpath("//p/@class") print(res) print("\n")
结果
[<Selector xpath='//p/@class' data='cp1 section'>, <Selector xpath='//p/@class' data='cp2'>]
提取节点中的文本内容
/text(): 提取当前选择节点的文本内容, 不包括子节点的文本.
//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表达式中是$定义变量, 类似于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>'>]
来源:https://www.cnblogs.com/brandonli/p/12654396.html