美文网首页
Python解析库

Python解析库

作者: Recalcitrant | 来源:发表于2019-08-14 15:20 被阅读0次

Python解析库

目录
一、lxml库
二、BeautifulSoup库
三、PyQuery库

一、lxml库

教程:https://www.w3school.com.cn/xpath/index.asp

1.安装lxml库

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ lxml

2.解析规则

解析规则:XPath

表达式 描述
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取所有子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
* 通配符,选择所有元素节点与元素名
@* 选取所有属性
[@attrib] 选取具有给定属性的所有元素
[@attrib='value'] 选取给定属性具有给定值的所有元素
[tag] 选取所有具有指定元素的直接子节点
[tag='text'] 选取所有具有指定元素并且文本内容是text节点

3.XPath运算符

运算符 描述 实例 返回值
or age=19 or age=20 如果age等于19或者等于20则返回true反正返回false
and age>19 and age<21 如果age等于20则返回true,否则返回false
mod 取余 5 mod 2 1
| 取两个节点的集合 //book | //cd 返回所有拥有book和cd元素的节点集合
+ 6+4 10
- 6-4 2
* 6*4 24
div 除法 8 div 4 2
= 等于 age=19 True或False
!= 不等于 age!=19 True或False
< 小于 age<19 True或False
<= 小于或等于 age<=19 True或False
> 大于 age>19 True或False
>= 大于或等于 age>=19 True或False

4.构建etree实例

(1)从文本构建

示例:

from lxml import etree
def load_text():
    text = """
    <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">third item</a></li>
            <li class="item-1"><a href="link4.html">forth item</a></li>
            <li class="item-0"><a href="link5.html">fifth item</a>
        </ul>
    </div>
    """

    html = etree.HTML(text)
    result = etree.tostring(html)
    print(result.decode("utf-8"))
运行结果

经过处理后的html代码会被自动修复,如添加一些缺失的标签。

(2)从文件构建

示例:

from lxml import etree
def load_text():
    html = etree.parse("./test.html", etree.HTMLParser())
    print(type(html))
    result = etree.tostring(html)
    print(result.decode("utf-8"))

注意:etree.tostring()方法返回的数据为bytes类型,需要调用decode方法将其转换成sgr类型。

5.节点选取

(1)选中所有节点

  • 选中所有节点

//*

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//*")
print(result)
  • 选中所有的某一类节点

//标签

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li")
print(result)

(2)选取子孙节点

①选取直接子节点

/标签
/child::标签

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li/a")
print(result)

②选取后代节点

//标签
/descendant::标签

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li//a")
print(result)

(3)选取祖先节点

①选取父节点

  • 方法1

/..

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//a/..")
print(result)
  • 方法2

/parent::

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//a/parent::*")
print(result)

②选取祖先节点

/ancestor::*
/ancestor::标签

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li[1]/ancestor::*")
print(result)

(4)选取兄弟节点

# 获取该节点后的所有兄弟节点以及这些兄弟节点的所有子孙节点
result = html.xpath("//li[1]/following::*")
print(result)

# 获取该节点后的所有兄弟节点以及这些兄弟节点的所有子孙节点中的第一个节点
result = html.xpath("//li[1]/following::*[1]")
print(result)

# 获取该节点后的所有兄弟节点
result = html.xpath("//li[1]/following-sibling::*")
print(result)

(5)属性匹配

  • 选取具有某属性的节点

[@属性]

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li[@class]")
print(result)

选取拥有class属性的li标签。

  • 选取具有某属性且其值符合要求的节点

[@属性=值]

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li[@class='item-0']")
print(result)

选取拥有属性class='item-0'的li标签。

(6)属性多值匹配

[contains(@属性, 值)]

text = """
<li class="li li-first"><a href="link1.html">first item</a></li>
"""
html = etree.HTML(text)
result = html.xpath("//li[@class='li']/a/text()")
print(result)

result = html.xpath("//li[contains(@class, 'li')]/a/text()")
print(result)
运行结果

(7)多属性匹配

[contains(@属性, 值) and @属性=值]
[contains(@属性, 值) or @属性=值]

text = """
<li class="li li-first" name='item'><a href="link1.html">first item</a></li>
"""
html = etree.HTML(text)
result = html.xpath("//li[contains(@class, 'li') and @name='item']/a/text()")
print(result)

(8)按顺序位置选取节点

# 选取第一个节点
html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li[1]/a/text()")
print(result)

# 选取最后一个节点
result = html.xpath("//li[last()]/a/text()")
print(result)

# 选取前两个节点
result = html.xpath("//li[position() < 3]/a/text()")
print(result)

# 选取倒数第三个节点
result = html.xpath("//li[last() - 2]/a/text()")
print(result)
运行结果

6.属性获取

(1)获取节点属性

/@*
/@属性

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//a[@href='link4.html']/../@class")
print(result)

获取拥有属性href='link4.html的a标签的父亲节点的class属性的值。

(2)获取节点内容

/text()

html = etree.parse("./test.html", etree.HTMLParser())
result = html.xpath("//li[@class='item-0']/text()")
print(result)

获取拥有属性class='item-0'的li标签的文本内容。

二、BeautifulSoup库

文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/

1.安装BeautifulSoup库

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ beautifulsoup4
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ bs4

2.解析

(1)文档解析语法

soup = BeautifulSoup(待解析文档, 解析器)

(2)解析器

  • 常用解析器
解析器 使用方法 性能
Python标准库 BeautifulSoup(html_doc,"html.parser") 执行速度适中
文档容错能力强
lxml HTML 解析器 BeautifulSoup(html_doc,"lxml") 执行速度快
容错能力强
要求安装lxml扩展
lxml XML 解析器 BeautifulSoup(html_doc,"xml")
BeautifulSoup(markup,["lxml", "xml"])
支持解析xml
执行速度快
要求安装外部扩展
html5lib解析器 BeautifulSoup(html_doc,"html5lib") 以浏览器的方式解析文档,生成HTML5格式文档
执行速度慢
最好的容错性
要求安装html5lib扩展
  • 解析器安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ lxml
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ html5lib

3.修复文档

soup = BeautifulSoup(html, "lxml")
print(soup.prettify())

4.节点选取

# 整个HTML文档
soup
# title节点的HTML文本
soup.title
# title节点的文本内容
soup.title.string
print(type(soup))
print(type(soup.title))
print(type(soup.title.string))
运行结果

(1)按标签名

# 获取节点名称
print(soup.title.name)

# 获取属性值(字典类型)
print(soup.p.attrs)
print(soup.p.attrs['name'])

# 获取文本内容(str类型)
print(soup.p.string)

# 嵌套选择
print(soup.head.title)

# 关联选择
# contents属性:选取直接子节点
print(soup.p.contents)

(2)按节点关系

# 获取直接子节点(返回列表)
print(soup.p.contents)

# 获取直接子节点(返回生成器)
for i, child in enumerate(soup.p.children):
    print(i, child)
    
# 获取所有子孙节点(返回生成器)
for i, child in enumerate(soup.p.descendants):
    print(i, child)

获取直接父节点:parent
获取祖先节点:parents
获取兄弟节点:

next_sibling(下一个兄弟节点) | previous_sibling(上一个兄弟节点)
next_siblings(后面的所有兄弟节点) | previous_siblings(前面的所有兄弟及诶单)

(3)find方法

  • find_all()方法:返回符合条件的所有节点元素
# 通过name查找
print(soup.find_all(name="ul"))
print(type(soup.find_all(name="ul")[0]))
print(soup.find_all(name="ul")[0].find_all(name='li'))

# 通过属性查找
print(soup.find_all(attrs={'id': 'list'}))
print(soup.find_all(attrs={'id': 'list', 'name': 'elements'}))
print(soup.find_all(id='list2'))
print(soup.find_all(class_='list'))

# 通过文本查找节点
import re
print(soup.find_all(text=re.compile('^1+')))
print(type(soup.find_all(text=re.compile('^1+'))[0]))
  • find():返回单个元素(即匹配的第一个元素)

find_parent() | find_parents()
find_next_sibling() | find_next_siblings()
find_previous_sibling() | find_previous_siblings()
find_next() | find_all_next():返回节点后 第一个|所有 符合条件的节点
find_previous() | find_all_previous():返回节点前 第一个|所有 符合条件的节点

(4)CSS选择器

soup.select("CSS选择器")

三、PyQuery库

1.安装PyQuery库

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pyquery

2.语法类似jQuery

相关文章

网友评论

      本文标题:Python解析库

      本文链接:https://www.haomeiwen.com/subject/ynewjctx.html