美文网首页
XPATH、CSS选择器及正则表达式

XPATH、CSS选择器及正则表达式

作者: han0710 | 来源:发表于2017-08-21 10:21 被阅读0次

    在爬虫采集数据的过程中,如何定位及匹配数据是必须解决的一项任务。最常用的定位方式有三种:XPATH,CSS选择器及正则表达式。以下我们来系统的学习他们。

    一、XPATH 语法

    参考文档:XPATH教程 from runoob

    1. Xpath是什么

    XPath是一个W3C标准,可以供XSLT、XPointer以及其他XML解析软件使用;它包含一个标准函数库;使用路径表达式在XML文档中进行导航。在爬虫学习中,我们最需要了解的就是最后一项:如何使用XPath路径表达式进行导航。在此之前,首先让我们学习下XPath的基本概念之一:节点。

    2. XPath节点及相关

    XPath中有七种类型的节点:元素,属性,文本,命名空间,处理指令,注释以及文档(根)节点。除了节点之外,还有基本值(Atomic value)的概念。

    基本值:无父或无子的节点。从定义上看,基本值是一种特殊节点,常见于文本。

    项目(Item):基本值或者节点。

    XML是被作为文档树来对待的,也因此会涉及根节点、父子节点等概念,下面让我们总结下节点关系。

    3. XPath节点关系

    父(Parent): 每个元素或属性都有一个父,即其直接上级节点。

    子(Children):元素节点可以有0、1或多个子,即其直接下级节点。

    兄弟(Sibling):拥有相同的父的节点或节点集合。

    先辈(Ancestor):某节点的父,父的父,以此类推十八代(虚指)。

    后代(Descendant):某节点的子,子的子,以此类推。

    了解了基本概念,接下来是语法。

    4. XPath语法

    4.1 节点选取

    nodename 选取当前节点的所有nodename子节点;

    / 从根节点选取,即绝对路径;

    // 从当前节点选取,即相对路径;

    . 选取当前节点;

    .. 选取当前节点的父节点;

    @ 选取属性。

    4.2 谓语(Predicates)

    结合实例解释如下:

    /bookstore/book[1] 选取bookstore子元素的第一个book元素;

    /bookstore/book[last()] 选取bookstore子元素的最后一个book元素;

    /bookstore/book[position()<3] 选取bookstore元素的前两个book元素;

    *之前提到XPath中包含一个标准函数库;last()和position()就是其中常见的例子。

    //title[@lang] 选取拥有lang属性的title元素;

    //title[@lang='eng'] 选取lang属性为'eng'的title元素;

    /bookstore/book[price>35.00] 选取bookstore元素中的所有book元素,且其中的price元素大于35.00。

    4.3 通配符

    * 匹配任何元素节点; @*匹配任何属性节点;node()匹配任何类型的节点。

    4.4 路径组合

    //book/title | //book/price 选取book元素的所有title和price元素。

    之前我们介绍了节点关系的概念,那么如何利用节点关系来定位节点呢,请看XPath轴。

    5. XPath轴(Axes)

    ancestor 选取当前节点的所有先辈;

    ancestor-or-self 选取当前节点及其所有先辈;

    descendant 选取当前节点的所有后辈;

    descendant-or-self 选取当前节点及其所有后辈;

    parent 选取当前节点的父节点;

    child 选取当前节点的子节点;

    following 选取当前节点之后的所有节点;

    following-sibling 选取当前节点之后的所有兄弟节点;

    preceding 选取当前节点之前的所有节点;

    preceding-sibling 选取当前节点之前的所有兄弟节点;

    self 选取当前节点;

    attribute 选取当前节点所有属性;

    namespace 选取当前节点的所有命名空间节点。

    用法,比如要查找<a>元素之后的<span>元素,使用'//a/following::span'。

    6. XPath运算符

    | 计算两个节点集;

    + - * div mod加减乘除求余;

    = != < <= > >= 比较;

    or and 或与。

    二、CSS选择器语法

    参考资料:CSS选择器 from w3school

    在定位元素时,CSS选择器和XPath经常可以相互替代。常用的CSS选择器如下:

    .class 根据class属性选择元素;

    #id 根据id属性选择元素;

    * 选择所有元素;

    element 选择所有element元素;

    element,element1 选择所有element及element1元素;

    element element1 选择element内部的所有element1元素;

    element>element1 选择element的element1子元素;

    element+element1 选择紧接在element之后的element1元素;

    [attribute] 选择带有attribute属性的所有元素;

    [attribute=value] 选择attribute属性值为value的所有元素;

    [attribute~=value] 选择attribute属性值包含value的所有元素;

    [attribute|=value] 选择attribute属性值以value开头的所有元素;

    a:link 选择所有未被访问的链接;a:visited 选择所有已被访问链接;a:hover 选择活动链接;

    element:focus 选择获得焦点的element元素;

    element:first-letter 选择element元素首字母;element:first-line 选择element元素首行;

    element:first-child 选择属于element父元素的第一个子元素的每个element元素;

    element:lang(language) 选择带有以language开头的lang属性值得每个element元素;

    ele1~ele2 选择前面有ele1元素的每个ele2元素;

    ele[attribute^=value] 选择attribute属性值以value开头的每个ele元素;

    ele[attribute$=value] 选择attribute属性值以value结尾的每个ele元素;

    ele[attribute*=value] 选择attribute属性值包含value的每个ele元素;

    ele:first-of-type 选择属于其父元素的首个ele元素的每个ele元素;

    ele:last-of-type 选择属于其父元素的最后ele元素的每个ele元素;

    ele:only-of-type 选择属于其父元素唯一的ele元素的每个ele元素;

    ele:only-child 选择属于其父元素的唯一子元素的每个ele元素;

    ele:nth-child(n) 选择属于其父元素的第n个子元素的每个ele元素;

    ele:nth-last-child(n) 选择属于其父元素的倒数第n个子元素的每个ele元素;

    ele:nth-of-type(n) 选择属于其父元素的第n个元素的每个ele元素;

    ele:nth-last-of-type(n) 选择属于其父元素的倒数第n个元素的每个ele元素;

    ele:last-child 选择属于其父元素最后一个子元素的每个ele元素;

    :root 选择文档根元素;

    ele:empty 选择没有子元素的每个ele元素;

    ele:target 选择当前活动的ele元素;

    ele:enabled 选择每个启用的ele元素;ele:disabled 选择每个禁用的ele元素;

    ele:checked 选择每个被选中的ele元素;

    :not(selector) 选择非selector的每个元素;

    ::selection 选择被用户选取的元素部分。

    三、正则表达式语法

    参考教程:正则表达式 from runoob

    当我们使用word或text之类的办公软件时,经常用到搜索和筛选来定位查找词语。这个功能很便利,但是它的不足之处也很明显。其中之一就是:作为过滤器的模式非常有限。相比之下,正则表达式可以实现前者的所有工作,而且更加强大和灵活。下面让我来看看,它是如何做到这一点的。

    1. 正则表达式记号

    普通字符 大小写字母,所有数字,所有标点和一些其他字符(如非打印字符)。

    非打印字符 

    \cx 匹配由x指明的控制字符;x的值必须为A-Za-z之一;否则c将被视为字母c;

    \f 匹配换页符;\n 匹配换行符;\r 匹配回车符; \s 匹配任何空白字符,包括空格、制表符、换页符等;\S 匹配任何非空白字符;\t 匹配任何制表符;\v 匹配垂直制表符。

    特殊字符

    ^ 匹配开始位置,在方括号中时,表示否定,即不接受该字符集合;$ 匹配结尾位置;

    * 匹配前面的子表达式0或多次; + 匹配前面的子表达式1或多次;

    ? 匹配前面的子表达式0或1次,或指定一个非贪婪限定符;

    . 匹配除换行符\n之外的任何单字符;

    \ 转义字符;

    | 指明两项之间的其中一个。

    () 标记一个子表达式的开始和结束位置。子表达式可以获得,供以后使用;

    [] 标记一个中括号表达式的开始;

    { } 标记限定符表达式的开始;

    限定符

    * + ? 见特殊字符

    {n} 匹配确定的n次;{n,} 至少匹配n次;{n,m} 匹配n到m次。

    定位符

    ^ $ 见特殊字符

    \b 匹配字边界(字与空格间的位置);\B 非字符边界

    子表达式

    前面提到,()可以标记一个子表达式,且该表达式可以被捕获缓存。如果这并不是你想要的,那么可以使用?:消除这种副作用,即将子表达式标记为非捕获元。

    除此之外,还有另外两个很重要的非捕获元?=和?!,前者称为正向预查,后者称为反向预查。两者还经常被称为零宽断言(正向、反向);此外还有逆序正向预查和逆序反向预查。

    正向预查(?=exp) a. 当单词同时满足前部匹配条件和exp时,返回前部匹配; b. exp非捕获

    举例: \b\w+(?=ing\b)  输入 singing and dancing 输出 sing和danc

    反向预查(?!exp) a. 当单词满足前部匹配条件且不满足exp时,返回前部匹配,b. exp非捕获

    逆序正向预查(?<=exp) a. 当单词同时满足exp和后部匹配条件时,返回后部匹配;b. exp非捕获;

    逆序反向预查(?<!exp) a. 当单词不满足exp且满足后部匹配条件时,返回后部匹配;b. exp非捕获;

    *名字很拗口,可以这么理解:正向、反向指的是要匹配的字符是在前面还是后面;正序、逆序指的是肯定还是否定子表达式。

    引用

    每个被捕获的子表达式都会存储在缓冲区,且被编号为1-99。每个缓冲区可以通过\n来访问,其中n为标识特定缓冲区的一位或两位十进制数。最简单,最有用的应用为查找文本中两个相同的相邻单词。

    2. 元字符

    \ ^ $ * + ? {n} {n,} {n,m} (pattern) (?:pattern) (?=pattern) (?!pattern) x|y [xyz] [^xyz] [a-z] [^a-z]

    \b \B \cx \f \n \r \s \S \t \v

    以上这些已经介绍过了,下面再看些常用的元字符。

    \d 匹配一个数字字符,即[0-9];\D 匹配一个非数字字符;

    \w 匹配包括下划线的任何单词字符,即[A-Za-z0-9];

    \W 匹配任何非单词字符;

    \xn 匹配n,其中n为十六进制,必须为确定的两个数字;

    \num 如果前面至少num个被捕获子表达式,则表示引用;否则,如果num为0-7的数字,则匹配八进制;

    \un 匹配n,其中n是四个十六进制数字表示的字符。

    了解了这么多的符号和运算,很容易想到一个问题,这些运算符的优先级是怎么样的?

    3. 运算符优先级

    优先级从高到低为:

    \ 转义符;

    (),[] 子表达式和中括号表达式;

    *,+,?,{} 限定符;

    ^,$,\任何元字符,任何字符 定位点和普通字符;

    | 选择。

    相关文章

      网友评论

          本文标题:XPATH、CSS选择器及正则表达式

          本文链接:https://www.haomeiwen.com/subject/jroorxtx.html