Python3 HTML数据解析(lxml/BeautifulSoup/JsonPath)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Rozol/article/details/79968795

Python3 HTML数据解析(lxml/BeautifulSoup/JsonPath)


本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.csdn.net/Rozol/article/details/79968795


以下代码以Python3.6.1为例
Less is more!

lxml

#!/usr/bin/env python
# coding=utf-8
__author__ = 'Luzhuo'
__date__ = '2018/4/16'

'''
    lxml 是一个 HTML/XML 的解析器, 主要用于解析和提取 HTML/XML 数据
    lxml由 C 实现的, 我们可以用 XPath 语法来快速的定位结点
    pip install lxml
    lxml-4.2.1
    xpath文档: http://www.w3school.com.cn/xpath/

'''

from lxml import etree

text = '''
<div>
    <ul>
        <li class="item_0">
           <a href="/i/0123">条目1</a>
        </li>
        <li class="item_1">
           <a href="/i/01234">条目2</a>
        </li>
        <li class="item_2">
            <a href="/i/012345">条目3</a>
        </li>
        <li class="item_0">
            <a href="/i/0123456">条目4</a>
        <li class="item_1">
            <a href="/i/01234567">条目5</a>
    </ul>
</div>
'''


# 第三方库lxml的演示
def lxml_demo():
    # 解析成html, 会自动修正html
    html = etree.HTML(text)
    # html = etree.parse('text.html')  # 从文件解析
    print(etree.tostring(html))

    # 使用xpath匹配
    result = html.xpath('//li')  # 所有<li>
    result = html.xpath('//li/@class')  # 所有<li>下的class属性
    result = html.xpath('//li/a[@href="/i/0123456"]')  # 所有<li>下<a>标签href属性为"/i/0123456"的标签
    result = html.xpath('//li[last()-1]/a/@href')  # 最后一个 -1 的<li>下<a>标签的href属性
    result = html.xpath('//a[contains(@href, "/i/")]')  # 模糊匹配

    html = html.xpath('//li[@class="item_0"]')[0]
    text = html.xpath('./a/@href')  # 获取a标签下href属性的值
    text = html.xpath('./a/text()')  # 获取a标签的内容

    print(result)


lxml_demo()

BeautifulSoup

#!/usr/bin/env python
# coding=utf-8
# beautifulsoup.py beautifulsoup演示

from urllib import request
from bs4 import BeautifulSoup
import re


'''
    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库
    Beautiful Soup 会载入整个文档, 解析整个DOM树, 所以内存消耗会比较大
    文档地址:http://beautifulsoup.readthedocs.io/zh_CN/latest
    pip install beautifulsoup4
    beautifulsoup4-4.6.0
'''

text = '''
<div>
    <ul>
        <li class="item_0">
           <a href="/i/0123">条目1</a>
        </li>
        <li class="item_1" id="link1">
           <a href="/i/01234">条目2</a>
        </li>
        <li class="item_2">
            <a href="/i/012345">条目3</a>
        </li>
        <li class="item_0" id="link1">
            <a href="/i/0123456">条目4</a>
        <li class="item_1">
            <a href="/i/01234567">条目5</a>
    </ul>
</div>
'''

def fun():

    '''
    解析库
        "html.parser": Python标准库 (内置, 速度适中, 容错能力强)
        "lxml": lxml HTML 解析器 (速度快, 文档容错能力强, 需要安装lxml) [推荐][pip install lxml]
        "xml": lxml XML 解析器 (速度快, 唯一支持XML的解析器, 需要安装lxml)
        "html5lib": html5lib (生成HTML5格式的文档, 以浏览器的方式解析文档, 容错能力最好, 速度慢) [pip install html5lib]
        不同的解析器, 解析出来的内容是不同的
    '''
    soup = BeautifulSoup(text, "lxml")
    soup = BeautifulSoup(open('text.html'))  # 打开本地文件
    print(soup.prettify())



    # 获取标签
    print(soup.li)  # 获取第一条<li>标签
    print(soup.li.a)  # 获取第一条<li>标签下<a>标签
    print(soup.ul.contents)  # <ul>标签所有(直接)子结点
    print(soup.ul.contents[1])
    for child in soup.ul.children: print(child)  # <ul>标签所有(直接)子结点(返回list生成器)
    for child in soup.descendants: print(child)  # 遍历所有(直接+间接)结点

    print(soup.li.a.name)  # 标签的名字
    print(soup.li.a.attrs)  # 标签的所有属性
    print(soup.li['class'])  # 所有属性名为'class'的值
    soup.li['class'] = 'b123'  # 修改属性内容
    soup.a.string = 'aaa'
    del soup.li['class']  # 删除属性

    print(soup.a.string)  # 标签内容, 没内容返回None
    for string in soup.stripped_strings: print(repr(string))  # 所有内容, 去除空格 (.strings 不去空格)
    print(soup.find_all('a')[0].get('href'))  # 获取标签里的内容
    print(soup.find_all('a')[0].get_text())  # 获取文本内容



    # --- 搜索方法 ---
    # limit=2 可限制返回数量 / recursive=False 只想搜索直接子结点
    print(soup.find('li'))  # 搜索一个标签
    print(soup.find_all("li"))  # 搜索全部标签
    print(soup.find_all(re.compile('^l')))  # (正则)
    print(soup.find_all(['li', 'a']))  # (list)
    print(soup.find_all(href="/i/0123"))  # 所有href="/i/0123"的属性 (属性名不能为python保留字, 如class)
    print(soup.find_all(text=re.compile('^条目')))  # 搜索所有内容, 支持参数 字符串 / 正则 / list



    # --- 选择方法 ---
    print(soup.select('li'))  # 搜索所有标签<li>
    print(soup.select('.item_0'))  # 搜索所有属性 class="item_0" 的标签
    print(soup.select('#link1'))  # 搜索所有id id="link1" 的标签
    print(soup.select("li#link1"))  # 组合(不同节点加空格, 同节点不加)
    print(soup.select("li#link1 a"))
    print(soup.select("li > a"))  # 通过子标签查找(>号分隔)
    print(soup.select('li[class="item_0"]'))  # <li>所有属性 class="item_0" 的标签
    print(soup.select('li a[href="/i/012345"]'))  # 组合



if __name__ == "__main__":
    fun()

JsonPath

#!/usr/bin/env python
# coding=utf-8
__author__ = 'Luzhuo'
__date__ = '2018/4/17'

'''
介绍
    JsonPath 主要用于从 JSON 文档中提取数据
    文档: http://goessner.net/articles/JsonPath/
    pip install jsonpath
    jsonpath-0.75

语法
  xpath  jsonpath   描述
    /       $      根节点
    .       @       现行节点
    /       .or[]   取子节点
    //      ..      就是不管位置,选择所有符合条件的条件
    *       *       匹配所有元素节点
    []      []      迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等)
    |       [,]     支持迭代器中做多选。
    []      ?()     支持过滤操作.
            ()      支持表达式计算
'''

import jsonpath
import json

json_str = '''
{ "store": {
    "book": [ 
      { "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      { "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": 12.99
      },
      { "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      { "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
'''

def funcs():
    jsonobj = json.loads(json_str)

    result = jsonpath.jsonpath(jsonobj, '$..author')  # 同xpath的 //author
    result = jsonpath.jsonpath(jsonobj, '$.store.book[*].author')  # 同xpath的 /store/book/author
    result = jsonpath.jsonpath(jsonobj, '$.store..price')  # 同xpath的 /store//price
    result = jsonpath.jsonpath(jsonobj, '$..book[3]')  # 同xpath的 //book[3]
    result = jsonpath.jsonpath(jsonobj, '$..book[-1:]')  # 同xpath的 //book[last()]
    result = jsonpath.jsonpath(jsonobj, '$..book[0,1]')  # 同xpath的 //book[position()<3]
    result = jsonpath.jsonpath(jsonobj, '$..book[?(@.price<10)]')  # 同xpath的 //book[price<10]

    print(result)


if __name__ == "__main__":
    funcs()

猜你喜欢

转载自blog.csdn.net/Rozol/article/details/79968795