天天看點

Python爬蟲中XML、XPath、lxml的使用

XML

  • XML(EXtensibleMarkupLanguage)
  • http://www.w3school.com.cn/xml/index.asp
<?xml version="1.0" encoding="utf-8"?>

<bookstore>
    <book category="cooking">
        <title lang="en">Everyday Italian</title>
        <author>Gidada De</author>
        <year>2018</year>
        <price>23</price>
    </book>
    
    <book category="education">
        <title lang="en">Python is Python</title>
        <author>Food War</author>
        <year>2008</year>
        <price>83</price>
    </book>

    <book category="sport">
        <title lang="en">Running</title>
        <author>Klaus Kuka</author>
        <year>2010</year>
        <price>43</price>
    </book>

</bookstore>
           
  • 概念:父節點,子節點,先輩節點,兄弟節點,後代節點

XPath

  • XPath(XML Path Language), 是一門在XML文檔中查找資訊的語言,
  • 官方文檔: 官方文檔
  • XPath開發工具
    • 開元的XPath表達式工具: XMLQuire
    • chrome插件: Xpath Helper
    • Firefox插件: XPath CHecker
  • 常用路徑表達式:
    • nodename: 選取此節點的所有子節點
    • /: 從根節點開始選
    • //: 選取元素,而不考慮元素的具體為止
    • .: 目前節點
    • …:父節點
    • @: 選取屬性
      • booksotre: 選取bookstore下的所有子節點
      • /booksotre: 選取根元素
      • booksotre/book: 選取bookstore的所有為book的子元素
      • //book: 選取book子元素
      • //@lang:選取名稱為lang的所有屬性
  • 謂語(Predicates)
    • 謂語用來查找某個特定的節點,被向前在方括号中
    • /bookstore/book[1]: 選取第一個屬于bookstore下叫book的元素
    • /bookstore/book[last()]: 選取最後一個屬于bookstore下叫book的元素
    • /bookstore/book[last()-1]: 選取倒數第二個屬于bookstore下叫book的元素
    • /bookstore/book[position()❤️]: 選取屬于bookstore下叫book的前兩個元素
    • /bookstore/book[@lang]: 選取屬于bookstore下叫book的,含有屬性lang元素
    • /bookstore/book[@lang=“cn”]: 選取屬于bookstore下叫book的,含有屬性lang的值是cn的元素
    • /bookstore/book[@price < 90]: 選取屬于bookstore下叫book的,含有屬性price的,且值小于90的元素
    • /bookstore/book[@price < 90]/title: 選取屬于bookstore下叫book的,含有屬性price的,且值小于90的元素的子元素title
  • 通配符
    • *

      : 任何元素節點
    • @*: 比對任何屬性節點
    • node(): 陪陪任何類型的節點
  • 選取多個路徑
    • //book/tile | //book/author : 選取book元素中的title和author元素
    • //tile | //price: 選取文檔中所有的title和price元素

lxml庫

  • python的HTML/XML的解析器
  • 官方文檔: 官方文檔
  • 需要安裝:conda install lxml
  • 功能:
    • 解析HTML
# v30.html
'''
安裝lxml
'''
from lxml import etree

'''
用lxml來解析HTML代碼
'''

text = '''
<div>
    <ul>
        <li class="item-0"> <a href="0.html" target="_blank" rel="external nofollow" > first item </a></li>
        <li class="item-1"> <a href="1.html" target="_blank" rel="external nofollow" > first item </a></li>
        <li class="item-2"> <a href="2.html" target="_blank" rel="external nofollow" > first item </a></li>
        <li class="item-3"> <a href="3.html" target="_blank" rel="external nofollow" > first item </a></li>
        <li class="item-4"> <a href="4.html" target="_blank" rel="external nofollow" > first item </a></li>
        <li class="item-5"> <a href="5.html" target="_blank" rel="external nofollow" > first item </a>
    </ul>
</div>
'''

# 利用etree.HTML把字元串解析成HTML文檔
html = etree.HTML(text)
s = etree.tostring(html)
print(s)

           
  • 檔案讀取
from lxml import etree

# 隻能讀取xml格式内容,html報錯
html = etree.parse("./v30.html")

rst = etree.tostring(html, pretty_print=True)
print(rst)

           
  • etree和XPath的配合使用
from lxml import etree

# 隻能讀取xml格式内容,html報錯
html = etree.parse("./v30.html")
print(type(html))

# 查找所有book元素
rst = html.xpath('//book')
print(type(rst))
print(rst)

# xpath的意識是,查找帶有category屬性值為sport的book元素
rst = html.xpath('//book[@category="sport"]')
print(type(rst))
print(rst)

# xpath的意識是,查找帶有category屬性值為sport的book元素下的year元素
rst = html.xpath('//book[@category="sport"]/year')
rst = rst[0]
print(type(rst))
print(rst.tag)
print(rst.text)