BeautifulSoup和etree的区别和使用场景
BeautifulSoup和etree的区别和使用场景
创建时间:2024年3月5日
BeautifulSoup
和 etree
都是用于解析HTML和XML文档的工具,但它们有一些不同之处,适用于不同的使用场景。以下是它们的主要区别和一些使用场景:
BeautifulSoup:
- 灵活而简单:
BeautifulSoup
提供了一种简单而灵活的方式来浏览、搜索和修改HTML/XML文档的树结构。- 主要用于提取和解析HTML内容,对HTML标签的操作非常直观。
- 解析器多样性:
BeautifulSoup
支持多种解析器,如 Python 标准库中的html.parser
,以及第三方的解析器如lxml
和html5lib
。- 解析器的选择取决于性能需求和HTML文档的特性。
- 处理糟糕的HTML:
BeautifulSoup
能够处理糟糕的、不规范的HTML,具有一定的容错性。
- 适用于初学者:
- 适用于初学者和快速开发,提供了易于使用的API。
etree (ElementTree):
- 更高效的解析:
etree
是lxml
库的一部分,相对于BeautifulSoup
在解析性能上更为高效。lxml
使用了C语言编写,因此通常比纯Python实现的解析器更快。
- XPath支持:
etree
支持XPath表达式,可以方便地使用XPath语法来定位和选择XML/HTML文档中的元素。- 对于复杂的文档结构或需要精准定位的情况,XPath是一种强大的选择。
- 更底层的控制:
etree
提供了更底层的控制,可以更灵活地操作XML文档。- 如果需要更多的控制和直接访问XML节点,
etree
可能更适合。
- 较小的内存占用:
lxml
的etree
通常占用较小的内存,适用于处理大型文档。
使用场景:
- 使用 BeautifulSoup 的场景:
- 当你主要关注HTML的易读性和可操作性,而不太关心性能。
- 当你处理糟糕、不规范的HTML文档时。
- 当你是初学者,希望使用简单而直观的API进行HTML解析。
- 使用 etree 的场景:
- 当你需要更高效的性能,特别是在处理大型文档时。
- 当你需要使用XPath表达式来进行精确的元素选择和定位。
- 当你希望在解析XML文档时获得更底层的控制。
使用的完整代码
import requests
from bs4 import BeautifulSoup
from lxml import etree
url = 'http://www.netbian.com/keai/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35'}
# response = requests.request("get", url=url, headers=headers)
# html = response.content.decode('gbk', errors='ignore') # 使用GBK解码,并忽略错误
# soup = BeautifulSoup(html, "lxml")
# # print(soup)
# for i in soup.find_all(attrs={"class": "list"}):
# # print(i)
# for o in i.find_all("img"):
# # print(o)
# print(o.get('src'))
#
resp = requests.get(url, headers=headers)
resp.encoding = resp.apparent_encoding
# 将响应内容解析为etree对象
xp = etree.HTML(resp.text)
# print(type(xp))
# 获取每页中的图片详情页链接
# img_url = xp.xpath("/html/body/div[@class='wrap clearfix']/div[@id='main']/div[@class='list']/ul/li/a/img/@src")
img_url = xp.xpath("//div[@class='list']/ul/li/a/img/@src")
print(img_url)
使用的案例
针对一个网站
http://www.netbian.com/keai/
假设我们需要抓取下面的src
需要抓取的数据:
先使用BeautifulSoup进行加载页面:
url = 'http://www.netbian.com/keai/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35'}
response = requests.request("get", url=url, headers=headers)
html = response.content.decode('gbk', errors='ignore') # 使用GBK解码,并忽略错误
soup = BeautifulSoup(html, "lxml")
print(soup)
处理我们需要的数据
# print(soup)
for i in soup.find_all(attrs={"class": "list"}):
# print(i)
for o in i.find_all("img"):
# print(o)
print(o.get('src'))
使用我们的etree 进行加载页面
resp = requests.get(url, headers=headers)
resp.encoding = resp.apparent_encoding
# 将响应内容解析为etree对象
xp = etree.HTML(resp.text)
是一个类。我们可以按照xpath进行提取数据
img_url = xp.xpath("/html/body/div[@class='wrap clearfix']/div[@id='main']/div[@class='list']/ul/li/a/img/@src")
print(img_url)
或者
img_url = xp.xpath("//div[@class='list']/ul/li/a/img/@src")
print(img_url)
结论:
在我看来,对比两者,使用etree
确实更为简洁。然而,etree
需要额外学习XPath表达式,这可能会增加一些学习成本。另一方面,BeautifulSoup返回的是HTML结构对象,这使其更适合于定位和提取所需内容。因此,大多数教学资料都倾向于使用BeautifulSoup。不过,对于有兴趣深入学习的同学来说,尝试将之前的抓取程序修改为使用etree
将是一个很好的实践机会。毕竟,学无止境,不断挑战和尝试新的方法和技术,将有助于我们不断提升自己的技能水平。
学习资料:
beautifulsoup
https://beautifulsoup.cn/
etree
https://docs.python.org/3/library/xml.etree.elementtree.html
https://www.runoob.com/xpath/xpath-tutorial.html