xpath tutorial

这篇文章主要是方便写爬虫,实验环境可以基于scrapy爬虫框架,操作页面就以煎蛋妹子图为例.

安装好scrapy后,直接使用命令 scrapy shell http://jandan.net/ooxx/page-1进入scrapy的交互模式,其中response变量中存放了响应对象,直接使用response.xpath函数就可以直接尝试xpath选择器啦。

基于树结构的简单实例

首先xpath是一种查询xml的方式,XML文档被组织称树的格式,因此,对树的基本概念可以直接应用到xpath上。直接上例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'''获得所有div元素,不管他在文档中的位置'''
response.xpath("//div")

'''获得所有根节点下的所有元素'''
response.xpath("/×")

'''获得所有id是‘sidebar’的元素,不管他在文档中的位置
response.xpath("//div[@id='sidebar']")

'''获得id是‘commentform’的所有元素,不管他在文档中的位置'''
response.xpath("//*[@id='commentform']")

'''获取左右文档中的id的值'''
response.xpath("//@id")

谓语

上面是对xpath的一个直观认识,使用上xpath表达式比css要稍微繁琐一些,但是却更强大。首先重要的一个概念就是“谓语”,谓语被嵌在方括号中,用来查找符合某个特定条件的节点。

在上面的案例中我们已经看到了谓语的使用实际上[@a=b]这种形式是通用的,a可以是id或class或者节点的任意属性。另外,下标也是谓语的一大类使用方式。

1
2
3
4
5
6
7
8
9
10
11
<!-- more -->
'''选取拥有id属性的所有div元素'''
response.xpath("//div[@id]")

'''选取body元素下的第一个div节点,注意从1开始'''
response.xpath("//body/div[1]")

'''选取body的div子节点的div子节点中的前两个'''
response.xpath("//body/div/div[position() < 3]")

'''直接进行元素的比较

多重选择

可以使用通配符×或者|符号进行多重选择。通配符的使用不多赘述。

1
2
'''选取所有body节点的直接a子节点和div子节点'''
response.xpath("//body/*/div | //body/*/a")

轴可定义相对于当前节点的节点集,例如子节点,子孙节点,父节点,祖宗节点,后继兄弟等等。轴的使用要配合“步”,步实际上就是对轴节点集的条件测试,如果无需测试,在“步”中使用通配符。

1
2
3
4
5
6
7
8
9
10
11
12
13
'''选取body的div子节点的所有孩子节点'''
response.xpath("//body/div/child::×")

'''选取body的div子节点的所有div孩子节点'''
response.xpath("//body/div/child::div")

'''选取a节点的所有祖先节点中的body节点
a = response.xpath("//body/div/a")[0]
a.xpath("ancestor::body")

'''选取a节点的所有后继兄弟
a = response.xpath("//body/div/a")[0]
a.xpath("following-sibling::*")

更多轴的使用:

函数

详见w3school

常用的函数:

1
2
3
4
5
6
7
8
'''text'''
response.xpath("//span[@class='tucao-like-container']")[0].xpath("span/text()")

'''contains'''
response.xpath("//div[contains(@id, 'foot')]")

'''position()'''
response.xpath("//body/div/div[position() < 3]")

Goal CSS 3 XPath
所有元素节点 * //*
所有p元素节点 p //p
所有p元素节点的子节点 p > *
根据ID选择元素 #foo //*[@id=’foo’]
根据class选择元素 .foo //*[contains(@class,’foo’)]
根据属性选择元素 *[title] //*[@title]
所有p节点的第一个子节点 p > *:first-child 0]
所有存在子节点的p节点 Not possible //p[a]
下一个元素节点 p + llowing-sibling::[0]

参考:

  1. W3school
  2. [译]XPath和CSS选择器
本站总访问量