Python爬虫:xml-xpath-lxml模块

一、什么是xml?

  • 定义:可扩展性标记语言
  • 特点:xml是具有自描述结构的半结构化数据
  • 作用:xml 主要设计宗旨是用来传输数据的,他还可以作为配置文件。

二、xml和html的区别

  • 1. 语法要求不同

    • html 不区分大小写,xml 区分,xml的语法要求更严格
    • html有时可以省去尾标签,xml 不能省略任何标签,严格按照嵌套首位结构
    • 只有xml中有自闭标签(没有内容的标签,只有属性)
    • 在 html 中属性名可以不带属性值,xml必须带属性值
    • 在 xml 中属性必须用引号括起来,html 中可不加引号
  • 2. 作用不同

    • html 主要设计用来显示数据,以及更好的显示数据
    • xml 主要设计宗旨就是用来传输数据
  • 3. 标记不同

    • xml 没有固定标记,html 的标记都是固定的,不能自定义。

三、xpath

什么是xpath

是一种筛选 HTML 或者 xml 页面元素的【语法】
一些名词:元素,标签,属性,内容
解析方法:dom 和 sax

xpath语法

选取节点

路径表达式意义
nodename选取此标签以及其所有子标签
/从根节点开始选取
//从任意节点开始,不考虑他们的位置。示例://book 从任何位置,取出所有的book标签
.从当前节点开始找
从父节点开始找
@选取属性,后面加标签的属性
text()选取内容

谓语

[ ]:写在谁的后面,就限定谁,一般用于限定元素或者标签
常见谓语意义
[@class]选取有class属性的节点
[@class=‘abc’]选取 class 属性为 abc 的节点
[contains(@href,‘baidu’)]选取 href 属性包含baidu 的标签
[1]选取第一个
[last()]选取最后一个
[last() - 1]选取倒数第二个
[position() > 2]跳过前两个
book[price > 30]选取属性 price 的值大于30的节点

通配符

* :匹配任意节点
@* :匹配任意属性

选取若干路径

| : 左边和右边的 xpath 选的内容都要,相当于 and的意思

lxml模块

  1. 导包

     from lxml import etree
    
  2. 将字符串形式的 xml内容解析为可以调用 xpath语法的element对象的方法

from lxml import etree

string = '''
<div>
    <ul>
        <li class="item-0"><a href="link1.html">first item</a></li>
        <li class="item-1"><a href="link2.html">second item</a></li>
        <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span>></a></li>
        <li class="item-1"><a href="link4.html">fourth item</a></li>
        <li class="item-0"><a href="link5.html">fifth item</a></li>
    </ul>
</div>
'''
html = etree.HTML(string)
print(html)
new_string = etree.tostring(html, pretty_print=True).decode('utf-8')
print(new_string)

引用外部html

from lxml import etree
# 读取外部文件
html = etree.parse('deml.html')
# 解析element对象
string = etree.tostring(html,pretty_print=True).decode('utf-8')

  1. 返回一个element元素后,使用xpath方法筛选数据
from lxml import etree

text='''
<div>
    <ul>
        <li class="item-0" >
            <a href="link1.html" class = "a_1">first item</a>
        </li>
        <li class="item-1">
            <a href="link2.html">second item</a>
        </li>
        <li class="item-inactive">
            <a href="link3.html" class = "a_2">123</a>
            <span class="span_item1" >span_text1</span>
        </li>
        <li class="item-1">
            test
            <a href="link4.html" class="bold">fourth item
                <span class="span_item2">span_text2</span>
            </a>
        </li>
        <li class="item-0">
            <a href="link5.html">fifth item</a>
        </li>
    </ul>
</div>
'''
tree = etree.HTML(text)
#1. 获取所有的 <li> 标签
li_list = tree.xpath('//li')
print(li_list)
#2.继续获取<li> 标签的所有 class属性
li_class = tree.xpath('//li/@class')
print(li_class)
#3.继续获取<li>标签下href 为 link1.html 的 <a> 标签
a = tree.xpath('//li/a[@href="link1.html"]')
print(a)
#4.获取<li> 标签下的所有 <span> 标签(包括孙子span)
spans = tree.xpath('//li//span')
print(spans)
#5.获取 <li> 标签下的<a>标签里的所有 class
a_class = tree.xpath('//li/a/@class')
print(a_class)
#6.获取最后一个 <li> 的 <a> 的 href
a_href = tree.xpath('//li[last()]/a/@href')
print(a_href)
#7.获取倒数第二个元素的内容
element_c = tree.xpath('//*[last()-1]/text()')
print(element_c)
#8.获取 class 值为 bold 的标签名
tagname = tree.xpath('//*[@class="bold"]')[0]
#标签元素.tag可以获取标签的内容
print(tagname.tag)

打印结果

[<Element li at 0x1cd643eed08>, <Element li at 0x1cd643eec88>, <Element li at 0x1cd643eed88>, <Element li at 0x1cd643eedc8>, <Element li at 0x1cd643eee08>]
['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
[<Element a at 0x1cd643eeec8>]
[<Element span at 0x1cd643eef08>, <Element span at 0x1cd643eef48>]
['a_1', 'a_2', 'bold']
['link5.html']
['123', '\n            test\n            ', '\n        ']
a
from lxml import etree
html = '''
<bookstore>
    <title>新华书店</title>
    <book href="http://www.langlang2017.com/">
        <title lang="eng">Harry Potter</title>
        <price>29.99</price>
    </book>
    <book>
        <title lang="zh">Learning XML</title>
        <price>39.95</price>
    </book>
    <book href="www.baidu.com">
        <title>python 大全</title>
        <price>99.95</price>
    </book>
</bookstore>
'''
tree = etree.HTML(html)
print(tree)
#(1)获取文档中的所有book节点的第一个book节点
first_book = tree.xpath('//bookstore/book[1]')
#(2)获取第一个book节点
first_book = first_book[0]
print(first_book)
#(3)获取first_book当前节点下的href
href = first_book.xpath('.//@href')
print(href)
#(4)获取当前节点的父节点下的book节点的href属性
hrefs = first_book.xpath('..//book/@href')
print(hrefs)
#(5)获取价格小于40的书的书名
book_name = tree.xpath('//book[price<40]/title/text()')
print(book_name)
#(6)获取价格等于99.95的书的书名
book_name = tree.xpath('//book[price=99.95]/title/text()')
print(book_name)
#(7)获取book标签下面的title和price标签
result = tree.xpath('//book/title|//book/price')
print(result)
#(8)获取属性href含有baidu字符串的book标签,获取此标签的书名
book_name = tree.xpath('//book[contains(@href,"baidu")]/title/text()')
print(book_name)
#(9)获取前面两个属于bookstore标签的字标签的book标签,获取此标签的书名
book_names = tree.xpath('//bookstore/book[position()<3]/title/text()')
print(book_names)
#(10)匹配任何属性节点
tags = tree.xpath('//*[@*]')
print(len(tags))
#(11)获取所有带有属性title标签,获取此标签的内容
name = tree.xpath('//title[@*]/text()')
print(name)

打印结果

<Element html at 0x1c94ec0ec88>
<Element book at 0x1c94ec0ed88>
['http://www.langlang2017.com/']
['http://www.langlang2017.com/', 'www.baidu.com']
['Harry Potter', 'Learning XML']
['python 大全']
[<Element title at 0x1c94ec0eec8>, <Element price at 0x1c94ec0ef08>, <Element title at 0x1c94ec0ef48>, <Element price at 0x1c94ec0ef88>, <Element title at 0x1c94ec0ee48>, <Element price at 0x1c94ec28048>]
['python 大全']
['Harry Potter', 'Learning XML']
4
['Harry Potter', 'Learning XML']
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值