lxml解析包(一):爬虫解析包lxml

文章目录

  • 一、XML和HTML的对比
    • 1.什么是xml?
    • 2.XML 和 HTML 的区别
      • 2.1 语法要求不同
      • 2.2 标记不同
      • 2.3 作用不同
  • 二、XPATH
    • 1.什么是XPath
    • 2.开始使用的前提
      • 2.1 文本转换为文档树
      • 2.2 外部文件转换为文档树
    • 3.介绍etree中的其他内容
      • 3.1 元素
      • 3.2 路径表达式
      • 3.3 通配符(匹配任意节点)
      • 3.4 谓语
      • 3.5 多个路径
      • 3.6 常用函数举例
      • 3.7 获取文本内容的两种方式( text() 和 .text)
      • 3.8 etree.tostring()将对象转为字符串
      • 3.9 xpath中的轴

一、XML和HTML的对比

1.什么是xml?

  • xml称为可拓展性标记语言
  • xml具有自描述特性,是一种半结构化数据
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 的标签需要我们自行定义。
  • XML 是 W3C 的推荐标准

W3School官方文档:http://www.w3school.com.cn/xml/index.asp

2.XML 和 HTML 的区别

他们两者都是用于操作数据或者结构数据,在结构上大致相同的,但他们在本质上却存在着明显的区别。

2.1 语法要求不同

  • 在html中不区分大小写,在xml中严格区分
  • 在html中,有时不严格,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略右半部分闭合标签。在xml中,是严格的树状结构,绝对不能省略任何标记
  • 在xml中,拥有单个标记二没有匹配的结束标记的元素必须用一个/字符作为结尾。
  • 在xml中,属性值必须分装在引号中。在html中,引号可用可不用。
  • 在html中属性名可以不带属性值,xml必须带
  • xml文档中,空白部分不会被解析器自动删除,但是html是过滤掉空格的

总结:xml的语法要求更严格。

2.2 标记不同

  • html使用固有的标记,xml没有固有标记

2.3 作用不同

  • xml主要用来传输数据
  • html主要用来显示数据,以及更好的显示数据

二、XPATH

1.什么是XPath

  • Xath (XML Path Language) 是一种语法,用来提取xml或者html内容的语法。

  • W3School官方文档:http://www.w3school.com.cn/xpath/index.asp

2.开始使用的前提

需要把xml或者html转换成文档树对象

2.1 文本转换为文档树

from lxml import etree
if __name__ == '__main__':
    doc='''
        
'''
html = etree.HTML(doc)#相当于将doc套入了 doc之中 html2=etree.XML(doc)# 原doc内容 result = etree.tostring(html) print(str(result,'utf-8'))

2.2 外部文件转换为文档树

index.html

<div>
            <ul>
                 <li class="item-0"><a href="link1.html">first itema>li>
                 <li class="item-1"><a href="link2.html">second itema>li>
                 <li class="item-inactive"><a href="link3.html">third itema>li>
                 <li class="item-1"><a href="link4.html">fourth itema>li>
                 <li class="item-0"><a href="link5.html">fifth itema> # 注意,此处缺少一个 li> 闭合标签
             ul>
         div>

test.py

from lxml import etree

# 读取外部文件 index.html
html = etree.parse('./index.html')
result = etree.tostring(html, pretty_print=True)    #pretty_print=True 会格式化输出
print(result)

3.介绍etree中的其他内容

3.1 元素

html --->  ...
div ---> 
...
a ---> ...

这里的元素和html中的标签一个意思。单独的元素是无法表达一个路径的,所以单独的元素不能独立使用

3.2 路径表达式

表达式 描述
nodename 选取此节点的所有子节点
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置
. 选取当前节点
选取当前节点的父节点
@ 选取属性

3.3 通配符(匹配任意节点)

通配符 描述
* 任意元素
@* 任意属性
node() 任意子节点(元素,属性,内容)

3.4 谓语

使用中括号来限定元素,称为谓语

表达式 描述
//a[3] 代表子元素排在第3个位置的元素
//a[last()] last() 代表子元素排在最后个位置的元素
//a[last()-1] 和上面同理,代表倒数第二个
//a[position() < 3] 位置序号小于3,也就是前两个,这里我们可以看出xpath中的序列是从1开始
//a[@href] 拥有href的元素
//a[@href=‘www’] href属性值为’www’的元素
//book[@price>2] price值大于2的元素

3.5 多个路径

用 | 连接两个表达式,可以进行 或 匹配

//book/title | //book/price

3.6 常用函数举例

函数 举例 描述
contains() //a[contains(@class,‘a’)] //a[contains(text(),‘b’)] a标签类名包含a字符 a标签文字中有包含b的
start-with() //a[starts-with(@class,‘a’)] a标签类名开头是a字符的,注意没有ends-with
text() //span/text() span标签下的文字
last() //span[last()] 取最后一个span标签
position() //span[position()❤️] //li[position()=2] 取前两个位置的span标签 li中第二个位置
node() //ul/node() 返回ul的所有子节点,不管这个子节点是什么类型(熟悉,元素,内容)

3.7 获取文本内容的两种方式( text() 和 .text)

from lxml import etree

doc = '''
    
'''
html = etree.XML(doc) print(html.xpath("//a/text()")) # ['1', '2' ] print(html.xpath("//a")[0].text) # 1 print(html.xpath("//ul")[0].text) # 一堆空格 print(html.xpath("//ul/text()")) # ['\n ', '\n ', '\n ', '\n wwwww\n ']

在这里插入图片描述

3.8 etree.tostring()将对象转为字符串

from lxml import etree

doc = '''
    
'''
html = etree.HTML(doc) ele = etree.tostring(html.xpath('//li[1]')[0]) print ele

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GzInqSTv-1602229835206)(C:\Users\qinfan\AppData\Roaming\Typora\typora-user-images\1602229783554.png)]

3.9 xpath中的轴

总共有八个轴关键字,parent,child,ancestor祖先,descendant后裔,following,following-sibling兄弟姐妹,preceding,preceding-sibling。具体含义如下:

表达式 描述
parent::div 上层父节点,你那叫div的亲生爸爸,最多有一个;
child::div 下层所有子节点,你的所有亲儿子中叫div的;
ancestor::div 上面所有直系节点,是你亲生爸爸或者你亲爹或者你亲爹的爸爸中叫div的;
descendant::div 下面所有节点,你的后代中叫div的,不包括你弟弟的后代;
following::div 自你以下页面中所有节点叫div的;
following-sibling::div 同层下节点,你所有的亲弟弟中叫div的;
preceding::div 同层上节点,你所有的亲哥哥以及他们的后代中叫div的;
preceding-sibling::div 同层上节点,你所有的亲哥哥中叫div的;

轴参考文章:https://www.bbsmax.com/A/kvJ33W3nJg/

你可能感兴趣的:([Python-网络爬虫入门])