目录
Xpath简介
1. Scrapy 的 Xpath 简介
(1)使用xpath查找HTML中的元素
2. Xpath 查找 html 元素
(2)"//"与"/"的使用
(3)使用"."进行Xpath连续调用
(4)extract与extract_first函数使用
(5)获取元素属性值
(6)获取节点的文本值
(7)多个文本节点值
(8)使用condition限定tag元素
(9)使用position()序号来确定所选择的元素
(10)使用"*"代表任何element元素,不包括Text、Comment的结点
(11)使用@*代表属性
(12)Xpath搜索元素的父结点
(13)搜索后面的兄弟结点
(14)搜索前面的兄弟结点
表达式
|
描述
|
例子
|
nodename
|
选取此节点
|
例: body ,选取 body 元素
|
/
|
绝对路径 , 表示当前节点的下一级节点元素。
|
例: /body ,当前节点下一级的 body 元素,
默认当前节点选取根元素
|
//
|
相对路径,全文档查找;
|
例: //title ,全文档搜索 title 元素 body//title,在 body 元素后代中搜索所有 title 元素。
|
.
|
当前节点
|
例: .//title ,在当前节点后代中搜索所有 title元素
|
@
|
选取属性
|
//node[@attribute] ,例包含 attribute 属性的节点node 。
|
*
|
通配符
|
/* ,绝对路径匹配任意节点, //* ,全文匹 配任意节点,@* ,匹配任意属性
|
函数/方法
|
功能描述
|
extract()
|
获取对象的元素文本的列表
|
extract_first()
|
获取对象的元素文本的列表的第一个元素
|
"/@attrName"
|
/@attrName" 获取元素的属性节点对象,用extract() 获取属性值
|
"/text()"
|
获取元素的文本节点对象,用 extract() 获取文本值
|
"/tag[condition]"
|
获取符合限定条件的元素对象,其中 condition 是由这个 tag 的属性、
文本等计算出的一个逻辑值。多个限定条件如下:
"tag[condition1][condition2]...[conditionN]" 或者:
"tag[condition1 and condition2 and ... and conditionN]"
|
position()
|
限定某元素对象,从 1 开始。可通过 and 、 or 等构造复杂的表达式
|
"element/parent::*"
|
获取元素的父亲节点对象
|
" element/folllowing-sibling::*"
|
所有后序同级兄弟节点
|
“element/preceding-sibling::*“
|
所有前序同级兄弟节点
|
# 使用Xpath查找HTML中的元素
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
Learning XML
39.95
'''
selector = Selector(text=htmlText)
print(type(selector)) #
print(selector) #
s = selector.xpath("//title") # 全文查找title 形成一个Selector的列表
print(type(s)) #
print(s) # [, ]
from scrapy.selector import Selector从 scrapy 中引入 Selector 类,这个类就是选择查找类。
selector=Selector(text=htmlText)使用 htmlText 的文字建立 Selector类,就是装载 HTML 文档,文档装载后就形成一个 Selector对象,就可以使用 xpath 查找元素。
print(type(selector)可看到 selector 是一个类型为 scrapy.selector.unified.Selector,这个类型是一个有 xpath 方法的类 型。
s=selector.xpath("//title")这个方法在文档中查找 所有 的的元素,其中"//" 表示文档中的任何位置。一般地: selector.xpath("//tagName")表示在权文档中搜索的 tags ,形成一个 Selector 的列表。
print(type(s))由于有两个元素,因此这是一个 scrapy.selector.unified.SelectorList类, 类似 scrapy.selector.unified.Selector的列表。
print(s)s 包含两个 Selector 对象,一个是, 另外一个是。
使用 “//” 表示文档下面的所有结点元素,用 “/” 表示当前结点的下一级结点元素
# "//"与"/"的使用
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
Learning XML
39.95
'''
selector = Selector(text=htmlText)
print(type(selector))
print(selector)
print("====================s1====================")
s1 = selector.xpath("//bookstore/book") # 搜索下一级的元素,找到2个
print(type(s1))
print(s1)
print("====================s2====================")
s2 = selector.xpath("//body/book") # 搜索下一级的元素,结果为空
print(type(s2))
print(s2)
print("====================s3====================")
s3 = selector.xpath("//body//book") # 搜索下元素,找到2个
print(type(s3))
print(s3)
print("====================s4====================")
s4 = selector.xpath("/body//book") # 搜索文档下一级的下的元素,结果为空,∵文档的下一级是元素,不是元素
print(type(s4))
print(s4)
print("====================s5====================")
s5 = selector.xpath("/html/body//book")
# 或 s5 = selector.xpath("/html//book") # 搜索元素,找到2个
print(type(s5))
print(s5)
print("====================s6====================")
s6 = selector.xpath("//book/title") # 搜索文档中所有下一级的元素,找到2个
print(type(s6))
print(s6) # 结果与 selector.xpath("//title") selector.xpath("//bookstore//title")一样
print("====================s7====================")
s7 = selector.xpath("//book//price") # # 搜索文档中所有下一级的元素,找到2个
print(type(s7))
print(s7) # 结果与 selector.xpath("//price")一样
运行结果:
====================s1====================
[, ]
====================s2====================
[]
====================s3====================
[, ]
====================s4====================
[]
====================s5====================
[, ]
====================s6====================
[, ]
====================s7====================
[, ]
使用 “.” 表示当前结点元素,使用 Xpath 可以连续调用,如果前一个 Xpath 返回一个 Selector 的列表,那么这个列表可以继续调用 Xpath
功能:为了每个列表元素调用 Xpath ,最后结果是全部元素调用 Xpath 的汇总
# 使用"."进行Xpath连续调用
from scrapy.selector import Selector
htmlText = '''
books
Novel
Harry Potter
29.99
TextBook
Learning XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book").xpath("./title")
# s = selector.xpath("//book").xpath("/title") # 结果是空的,因为后面的 xpath("/title")从文档开始搜索。
# s = selector.xpath("//book").xpath("//title") # 结果有10个元素,因为每个 都驱动xpath("//title")在全文档搜索 元素,每次都搜索到5个元素。
for e in s:
print(e)
运行结果:
注意: 如果 xpath 连续调用时不指定是从前一个 xpath 的结果元素开始的,那么默认是从全文档开始的,结果会不一样,例如:s=selector.xpath("//book").xpath("/title") 结果是空的,因为后面的 xpath("/title")从文档开始搜索。 s=selector.xpath("//book").xpath("//title") 结果有 10 个元素,因为每个都驱动 xpath("//title") 在全文档搜索元素,每次都搜索到 5 个元素。
# extract与extract_first函数使用
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book/price")
print(type(s), s)
s = selector.xpath("//book/price").extract()
print(type(s), s)
s = selector.xpath("//book/price").extract_first()
print(type(s), s)
运行结果:
[ , ]
[' 29.99 ', '39.95 ']
29.99
# 获取元素属性值
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book").xpath("./@id")
print(s) # [, ]
print(s.extract()) # ['b1', 'b2']
for e in s:
print(e.extract()) # b1 \n b2
运行结果:
[
, ]
['b1', 'b2']
b1
b2
# 获取节点的文本值
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book/title/text()")
print(s)
print(s.extract()) # ['Harry Potter', '学习 XML']
for e in s:
print(e.extract()) # Harry Potter \n 学习 XML
运行结果:
[
, ]
['Harry Potter', '学习 XML']
Harry Potter
学习 XML
# 多个文本节点值
from scrapy.selector import Selector
htmlText = '''
Hary Potter
29.99
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book/title/text()")
print(s)
print(s.extract()) # ['ary ', 'otter']
for e in s:
print(e.extract())
运行结果:
[
, ]
['ary ', 'otter']
ary
otter
# 使用condition限定tag元素
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book/title[@lang='chinese']/text()")
print(s.extract_first()) # 学习 XML
s = selector.xpath("//book[@id='b1']/title")
print(s.extract_first()) # Harry Potter
运行结果:
学习 XML
Harry Potter
# 使用position()序号来确定所选择的元素
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book[position()=1]/title") # 选择第一个元素下的title
print(s.extract_first()) # Harry Potter
s = selector.xpath("//book[position()=2]/title") # 选择第二个元素下的title
print(s.extract_first()) # 学习 XML
运行结果:
Harry Potter
学习 XML
# 使用"*"代表任何element元素,不包括Text、Comment的结点
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//bookstore/*/title")
print(s.extract()) # ['Harry Potter ', '学习 XML ']
运行结果:
['
Harry Potter ', '学习 XML ']
# 使用@*代表属性
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//book[@*]/title") # 搜索任何包含属性的元素下面的
print(s.extract()) # ['学习 XML ']
s = selector.xpath("//@*") # 搜索文档中所有属性结点
print(s.extract()) # ['english', 'b2', 'chinese']
运行结果:
['
学习 XML ']
['english', 'b2', 'chinese']
# Xpath搜索元素的父结点
from scrapy.selector import Selector
htmlText = '''
Harry Potter
29.99
学习 XML
39.95
'''
selector = Selector(text=htmlText)
s = selector.xpath("//title[@lang='chinese']/parent::*") # 等价 /parent::book
print(s.extract()) # ['\n 学习 XML \n 39.95 \n ']
运行结果:
['
\n ']学习 XML \n39.95 \n
# 搜索后面的兄弟结点
from scrapy.selector import Selector
htmlText = """A1
B1
C1
DE
B2
C2 """
selector = Selector(text=htmlText)
s = selector.xpath("//a/following-sibling::*") # 搜素结点后面的兄弟结点
print(s.extract()) # ['B1', 'C1 ', 'DE ', 'B2', 'C2 ']
s = selector.xpath("//a/following-sibling::*[position()=1]") # 搜索结点后面的第1个兄弟结点
print(s.extract()) # ['B1']
s = selector.xpath("//b[position()=1]/following-sibling::*") # 搜索第一个结点后面的兄弟结点
print(s.extract()) # ['C1 ', 'DE ', 'B2', 'C2 ']
s = selector.xpath("//b[position()=1]/following-sibling::*[position()=1]") # 搜索第一个结点后面的第1个兄弟结点
print(s.extract()) # ['C1 ']
运行结果:
['B1', '
C1 ', 'D ', 'B2', 'E C2 ']
['B1']
['C1 ', 'D ', 'B2', 'E C2 ']
['C1 ']
# 搜索前面的兄弟结点
from scrapy.selector import Selector
htmlText = """A1
B1
C1
DE
B2
C2 """
selector = Selector(text=htmlText)
s = selector.xpath("//a/preceding-sibling::*")
print(s.extract()) # []
s = selector.xpath("//b/preceding-sibling::*[position()=1]") # 是所有前面的第1个兄弟结点
print(s.extract()) # ['A1', 'DE ']
s = selector.xpath("//b[position()=2]/preceding-sibling::*") # 是第二个前面的所有兄弟结点
print(s.extract()) # ['A1', 'B1', 'C1 ', 'DE ']
s = selector.xpath("//b[position()=2]/preceding-sibling::*[position()=1]") # 这里的position()=1指的是前1个兄弟结点
print(s.extract()) # ['DE ']
运行结果: