什么是XPath
就像上一篇我们说的那样——XPath 是一门在 XML 文档中查找信息的语言;XPath 用于在 XML 文档中通过元素和属性进行导航 参考:https://www.cnblogs.com/scriptchild/p/10235180.html 官方一些就是: XPath 使用路径表达式在 XML 文档中进行导航 XPath 包含一个标准函数库 XPath 是 XSLT 中的主要元素 XPath 是一个 W3C 标准
借用一张图
如何使用XPath
XPath 是 XSLT 标准中的主要元素 在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点 XML 文档是被作为节点树来对待,树的根被称为文档节点或者根节点 #啥子Parent—Childre—Sibling 哦 ,我这全部晓不得 晓得是囊个意思就OK 搞懂语法晓得囊个用就OJBK
举个使用XPath的爬虫例子
#举一个例子——豆瓣肖申克信息抓取 """ 语法: 1.// 双斜杠 定位根节点,会对全文进行扫描,在文档中选取所有符合条件的内容,以列表的形式返回。 2./ 单斜杠 寻找当前标签路径的下一层路径标签或者对当前路标签内容进行操作 3./text() 获取当前路径下的文本内容 4./@xxxx 提取当前路径下标签的属性值 5.| 可选符 使用|可选取若干个路径 如//p | //div 即在当前路径下选取所有符合条件的p标签和div标签 6. . 点 用来选取当前节点 7、 .. 双点 选取当前节点的父节点 """ #在运用到python抓取时要先转换为xml #Import lxml #首先要先导入库 #etree.HTML()#这个就是转换为xml的python的语法,HTML括号内填入目标站点的源码 """ 截取: //*[@id="content"]/h1/span[1] //*[@id="info"]/span[1]/span[2]/a //*[@id="info"]/span[3]/span[2]/span[1]/a //*[@id="info"]/span[13] """ import requests from lxml import etree url = 'https://movie.douban.com/subject/1292052/' data = requests.get(url).text s = etree.HTML(data) # 在电影标题对应的代码上依次点击 右键 > Copy > Copy XPath,获取电影名称的Xpath: film = s.xpath('//*[@id="content"]/h1/span[1]/text()') #片名 director=s.xpath('//*[@id="info"]/span[1]/span[2]/a/text()') #导演 actor1=s.xpath('//*[@id="info"]/span[3]/span[2]/a[1]/text()') #主演1 actor2=s.xpath('//*[@id="info"]/span[3]/span[2]/a[2]/text()') #主演2 actor3=s.xpath('//*[@id="info"]/span[3]/span[2]/a[3]/text()') #主演3 time=s.xpath('//*[@id="info"]/span[13]/text()') #电影片长 # print(film,director,actor1,actor2,actor3,time) print('电影名称:',film) print('导演:',director) print('主演::',actor1,actor2,actor3) print('电影片长:',time)
XPath语法
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
路径表达式:
表达式 | 描述 |
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
实例
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
路径表达式 | 结果 |
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
谓语
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
实例
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
/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[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 | 描述 |
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
再举一个爬虫例子作为对比
#这里是豆瓣Top250 from lxml import etree import requests import time for a in range(10): url = 'https://book.douban.com/top250?start={}'.format(a*25) data = requests.get(url).text s=etree.HTML(data) file=s.xpath('//*[@id="content"]/div/div[1]/div/table') time.sleep(3) for div in file: title = div.xpath("./tr/td[2]/div[1]/a/@title")[0] href = div.xpath("./tr/td[2]/div[1]/a/@href")[0] score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0] num=div.xpath("./tr/td[2]/div[2]/span[3]/text()")[0].strip("(").strip().strip(")").strip() scrible=div.xpath("./tr/td[2]/p[2]/span/text()") if len(scrible) > 0: print("{},{},{},{},{}\n".format(title,href,score,num,scrible[0])) else: print("{},{},{},{}\n".format(title,href,score,num))
总结
学习XPath就到这了,还有很多地方没注意到,学无止境——加油!
HTML+JavaScript+CSS ——正则
正则是一个大家伙啊,让我想想怎么去搞定他,可棘手啦。
补充
//元素标签名[@属性名='具体内容'] 例如: //div[@class='box'],查找class为box的div //元素标签名[第几个] 例如: //div[@class='box'][2],查找符合条件的第2个div //元素1/@属性名 例如://ul/li/div/a/img/@src, 查找ul下的li下的div下的a下的img标签的src属性 //元素/text() 例如://a/text(), 获取a标签之间的文本(一级文本) //元素//text() 例如://div[@class='box']//text(), 获取class为div下的所有文本 //元素[contains(@属性名,'相关属性值')] 例如://div[contains(@class,'zhangsan')] 查找class中包含zhangsan的div //*[@属性='值'] 例如://*[@name='lisi']查找所有name为lisi的元素
突然看到就几篇好文,在此推荐(哇,我也还在看呐,看了好几遍了,非常Nice)
参考网址:http://www.cnblogs.com/qingchunjun/p/4208159.html
xpath详解:http://www.cnblogs.com/ktgu/archive/2009/04/16/1353246.html (╭(╯^╰)╮,早知道有那么好的文章,我就直接XXOO了,哈哈)