第8讲爬虫实例授课教师:张瑾8.1正则表达式8.1什么是正则表达式正则表达式是可以匹配文本片段的模式。最简单的正则表达式就是普通字符串,可以匹配其自身。8.1.1通配符正则表达式可以匹配多于一个的字符串,你可以使用一些特殊字符创建这类模式。比如点号“.”可以匹配任何字符(除了换行符),所以正则表达式‘.ython’可以匹配字符串‘python’和‘jython’。它还能匹配‘qython’、‘+ython’或者‘ython’(第一个字母是空格),但是不会匹配‘cpython’或者‘ython’这样的字符串,因为点号只能匹配一个字母,而不是两个或零个。018.1正则表达式8.1.2对特殊字符进行转义你需要知道:在正则表达式中如果将特殊字符作为普通字符使用会遇到问题,这很重要。比如,假设需要匹配字符串‘python.org’,直接用‘python.org’模式可以么?这么做是可以的,但是这样也会匹配‘pythonzorg’,这可不是所期望的结果(点号可以匹配除换行符外的任何字符,还记得吧?)。为了让特殊字符表现得像普通字符一样,需要对它进行转义(escape)——在它前面加上反斜线。因此,在本例中可以使用‘python\\.org’,这样就只会匹配‘python.org’了。注意为了获得re模块所需的单个反抖线,我们要在字符串中使用两个反料线——为了通过解释器进行转义。这样就需要两个级别的转义了:(1)通过解释器转义;(2)通过re模块转义(事实上,有些情况下可以使用单个反料线,让解释器自动进行转义,但是别依赖这种功能)。如果厌烦了使用双料线,那么可以使用原始字符串,比如r‘python\.org’。018.1正则表达式8.1.3字符集匹配任意字符可能很有用,但有些时候你需要更多的控制权。你可以使用中括号括住字符串来创建字符集(characterset)。字符集可以匹配它所包括的任意字符,所以‘[pj]ython’能够匹配‘python’和‘jython’,而非其他内容。你可以使用范围,比如‘[a-z]’能够(按字母顺序)匹配a到z的任意一个字符,还可以通过一个接一个的方式将范围联合起来使用,比如‘[a-zA-Z0-9]’能够匹配任意大小写字母和数字(注意字符集只能匹配一个这样的字符)。为了反转字符集,可在开头使用^字符,比如‘[^abc]’可以匹配任何除了a,b和c之外的字符。注意:点号、星号和问号等特殊字符在模式中用做文本字符而不是正则表达式运算符,在字符集中,没必要进行转义。如果脱字符^出现在字符集的开头,需要对其进行转义。018.1正则表达式8.1.4选择符和子模式在字符串的每个字符都各不相同的情况下,字符集是很好用的,但如果只想匹配字符串‘python’和‘perl’呢?你就不能使用字符集或者通配符来指定某个特定的模式了。取而代之的是用于选择项的特殊字符:管道符号‘|’。因此,所需的模式可以写成‘python|perl’。但是,有些时候不需要对整个模式使用选择运算符,只是模式的一部分。这时可以使用圆括号括起需要的部分,或称子模式(subparttern)。前例可以写成‘p(ython|erl)’。(注意,术语子模式也适用于单个字符。)018.1正则表达式8.1.5可选项和重复子模式在子模式后面加上问号,它就变成了可选项。它可能出现在匹配字符串中,但并非必需的。例如,r‘(http://)?()?python\.org’只能匹配下列字符串:‘’‘’‘’‘python.org’重复子模式有:(pattern)?允许模式出现0次到1次,最多出现1次。(pattern)*允许模式出现0次到多次。(pattern)+允许模式出现1次到多次。(pattern){m,n}允许模式出现m次到n次。018.1正则表达式8.1.6字符串的开始和结尾目前为止,所出现的模式匹配都是针对整个字符串的,但是也能寻找匹配模式的子字符串,比如字符串‘’中的子字符串‘’会能够匹配模式‘w+’。在寻找这样的子字符串时,确定子字符串位于整个字符串的开始还是结尾是很有用的。比如,只想在字符串的开头而不是其他位置匹配‘ht+p’,那么就可以使用脱字符‘^’标记开始:‘^ht+P’会匹配‘’(以及‘htttttp://python.org’),但是不匹配‘’。类似地,字符串结尾用美元符号($)标识。018.1正则表达式8.1.7re模块•变量代表(或者引用)某值的名字,是计算机保留内存位置用来存储某值。这意味着,当创建一个变量,那么它在内存中保留一些空间。•根据一个变量的数据类型,解释器分配内存,并决定如何可以被存储在所保留的内存中。因此,通过分配不同的数据类型的变量,可以存储整数,小数或字符在这些变量中。•变量名必须是大小写英文、数字和_的组合,不能用数字开头。Python的变量不必显式地声明保留的存储器空间。当分配一个值给一个变量的声明将自动发生。用“=”来赋值给变量。举例:输入:a=‘ABC’时,Python解释器干了两件事情:在内存中创建了一个'ABC'的字符串;在内存中创建了一个名为a的变量,并把它指向'ABC‘思考:若在交互式解释下输入:a=‘ABC’b=aa='XYZ'printb后得到的结果是什么?018.2XPath基础知识8.2.1XPath简介8.2.1.1什么是XPath?•XPath使用路径表达式在XML文档中进行导航•XPath包含一个标准函数库•XPath是XSLT中的主要元素•XPath是一个W3C标准8.2.1.2XPath路径表达式•XPath使用路径表达式来选取XML文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。8.2.1.3XPath标准函数•XPath含有超过100个内建的函数。这些函数用于字符串值、数值、日期和时间比较、节点和QName处理、序列处理、逻辑值等等。018.2XPath基础知识8.2.1XPath简介8.2.1.4XPath在XSLT中使用•XPath是XSLT标准中的主要元素。•XQuery和XPointer均构建于XPath表达式之上。XQuery1.0和XPath2.0共享相同的数据模型,并支持相同的函数和运算符。8.2.1.5XPath是W3C标准•XPath于1999年11月16日成为W3C标准。•XPath被设计为供XSLT、XPointer以及其他XML解析软件使用。018.2XPath基础知识8.2.2XPath术语8.2.2.1节点(Node)在XPath中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。请看下面这个XML文档:018.2XPath基础知识8.2.2XPath术语8.2.2.2基本值(或称原子值,Atomicvalue)基本值是无父或无子的节点。基本值的例子:8.2.2.3节点关系•父(Parent):每个元素以及属性都有一个父。在上面的例子中,book元素是title、author、year以及price元素的父。•子(Children):元素节点可有零个、一个或多个子。在上面的例子中,title、author、year以及price元素都是book元素的子。•同胞(Sibling):拥有相同的父的节点。在上面的例子中,title、author、year以及price元素都是同胞。•先辈(Ancestor):某节点的父、父的父等。在上面的例子中,title元素的先辈是book元素和bookstore元素。•后代(Descendant):某个节点的子,子的子等。在下面的例子中,bookstore的后代是book、title、author、year以及price元素。018.2XPath基础知识8.2.3XPath语法8.2.3.1选取节点XPath使用路径表达式在XML文档中选取节点。节点是通过沿着路径或者step来选取的。下面列出了最有用的路径表达式:01表达式描述nodename选取此节点的所有子节点。/从根节点选取。//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。.选取当前节点。..选取当前节点的父节点。@选取属性。8.2XPath基础知识8.2.3XPath语法8.2.3.1选取节点实例:01路径表达式结果bookstore选取bookstore元素的所有子节点。/bookstore选取根元素bookstore。注释:假如路径起始于正斜杠(/),则此路径始终代表到某元素的绝对路径!bookstore/book选取属于bookstore的子元素的所有book元素。//book选取所有book子元素,而不管它们在文档中的位置。bookstore//book选择属于bookstore元素的后代的所有book元素,而不管它们位于bookstore之下的什么位置。//@lang选取名为lang的所有属性。8.2XPath基础知识8.2.3XPath语法8.2.3.2谓语(Predicates)谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。实例:01路径表达式结果/bookstore/book[1]选取属于bookstore子元素的第一个book元素。/bookstore/book[last()]选取属于bookstore子元素的最后一个book元素。/bookstore/book[last()-1]选取属于bookstore子元素的倒数第二个book元素。/bookstore/book[position()3]选取最前面的两个属于bookstore元素的子元素的book元素。//title[@lang]选取所有拥有名为lang的属性的title元素。//title[@lang='eng']选取所有title元素,且这些元素拥有值为eng的lang属性。/bookstore/book[price35.00]选取bookstore元素的所有book元素,且其中的price元素的值须大于35.00。/bookstore/book[price35.00]/title选取bookstore元素中的book元素的所有title元素,且其中的price元素的值须大于35.00。8.2XPath基础知识8.2.3XPath语法8.2.3.3选取未知节点XPath通配符可用来选取未知的XML元素。实例:01通配符描述*匹配任何元素节点。@*匹配任何属性节点。node()匹配任何类型的节点。路径表达式结果/bookstore/*选取bookstore元素的所有子元素。//*选取文档中的所有元素。//title[@*]选取所有带有属性的title元素。8.2XPath基础知识8.2.3XPath语法8.2.3.4选取若干路径通过在路径表达式中使用“|”运算符,可以选取若干个路径。实例:01路径表达式结果//book/title|//book/price选取book元素的所有title和price元素。//title|//price选取文档中的所有title和price元素。/bookstore/book/title|//price选取属于bookstore元素的book元素的所有title元素,以及文档中所有的price元素。8.2XPath基础知识8.2.4XPathAxes(轴)8.2.4.1XPath轴轴可定义相对于当前节点的节点集。01轴名称结果ancestor选取当前节点的所有先辈(父、祖父等)。ancestor-or-self选取当前节点的所有先辈(父、祖父等)以及当前节点本身。attribute选取当前节点的所有属性。child选取当前节点的所有子元素。descendant选取