一、BeautifulSoup与lxml简介

1.1BeautifulSoup简介

Beautiful Soup是一个用于解析 HTML 和 XML 文档的 Python 库,广泛应用于网页抓取和数据提取。它能够自动修复不规范的标签,提供直观的方法来遍历、搜索和修改文档结构。

Beautiful Soup支持多种解析器(如 html.parser 和 lxml),并提供强大的搜索功能,包括 find() 和 find_all() 方法,简化了数据提取过程。
在这里插入图片描述

1.2lxml简介

lxml支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高

XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。

XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等,几乎所有想要定位的节点,都可以用XPath来选择。
在这里插入图片描述

1.3对比

BeautifulSoup与lxml是两种常用的处理html文件的软件包,lxml基于C语言开发,所以lxml处理速度更快。经过实际测试,处理相同的html文件,即使BeautifulSoup使用lxml解析器,lxml速度也比BeautifulSoup速度快上数倍

二、Beautifulsoup查找元素并获取元素属性

2.1查找元素

示例代码如下:

from bs4 import BeautifulSoup

with open(filePath, 'r', encoding = 'gbk', errors = 'replace') as f:
	html_content = f.read()

#soup = BeautifulSoup(html_content, 'html.parser')#BeautifulSoup使用html解析器,速度上低于lxml解析器
soup = BeautifulSoup(html_content, 'lxml')#BeautifulSoup使用lxml解析器
div_element = soup.find('div')#查找单个div元素,找不到会返回None
a_elements = div_element.find_all('a')#在div元素内部查找所有a元素,返回一个列表
div_elements = soup.find_all('div', class_='class01')#查找所有class为class01的div元素
div_elements = soup.find_all('div', attrs={'class':'class01'})#与上一行代码功能相同
div_elements = soup.find_all('div', id='id01')#查找所有id为id01的div元素
div_elements = soup.find_all('div', attrs={'id':'id01'})#与上一行代码功能相同
div_parent_element = div_elements[0].parent#获取父元素
for child in div_elements[0].children):#获取子元素
    print(child)

div_nextSib = div_elements[0].next_sibling#获取元素的下一个兄弟元素
div_preSib = div_elements[0].previous_sibling#获取元素的上一个兄弟元素

上面代码中查找全部元素使用的是find_all函数,使用findAll函数也可达到相同的查找效果。

获取兄弟元素时,如没有兄弟元素则返回None,如果html文件中标签与标签间存在空行间隔,那么返回的是一个换行字符:‘\n’,而不是元素

2.2获取元素属性

示例代码如下:

div_attrDict = div_element.attrs#以字典格式返回元素的全部属性,包括id、class等
div_class = div_attrDict['class']#获取class属性
div_class = div_element.get('class')#与上句效果相同,获取class属性
div_text01 = div_element.string#获取div标签间的文本,文本不包括子标签的文本
div_text02 = div_element.text#获取div标签间的文本,文本还包括子标签的文本
for str in div_elements[0].strings:#逐个标签获取div标签间的文本
	print(str)

三、lxml查找元素并获取元素属性

3.1查找元素

示例代码如下:

from lxml import etree

with open(filePath, 'r', encoding = 'gbk', errors = 'replace') as f:
	html_content = f.read()

lxml_page = etree.HTML(html_content)
div_elements = lxml_page.xpath('//div')#查找html文件中所有div元素,返回一个列表
a_elements = div_elements[0].xpath('.//a')#在div元素内部查找所有a元素,返回一个列表
div_elements = lxml_page.xpath('//div[@class="class01"]')#查找所有class为class01的div元素
div_elements = lxml_page.xpath('//div[@id="id01"]')#查找所有id为id01的div元素
div_elements = lxml_page.xpath('//div[contains(@id,"test")]')#查找所有id包含test的div元素
a_elements = lxml_page.xpath('//div[@id="id01"]/a[@id="id02"]')#查找所有id为id01的div元素下的id为id02的a元素
a_parent_element = a_elements[0].getparent()#获取父元素
a_new_element = etree.Element("a")#创建新的a元素
a_parent_element.insert(a_parent_element.index(a_elements[0]), a_new_element)#在父元素中旧a元素前插入新a元素
a_parent_element.remove(a_elements[0])#从父元素中移除旧a元素

相较于BeautifulSoup,lxml可以直接实现嵌套元素的查找,虽然xpath编写较为麻烦,但是查找元素更为灵活。

需要注意的是,当所查找元素具有多个class时,如果直接指定查找其中一个class值,那么lxml会查找不到,而Beautifulsoup可以查找到,使用xpath的contains才可以使lxml查找到

3.2获取元素属性

示例代码如下:

a_href = a_element.get('href')#获取a元素href属性
div_class = div_element.get('class')#获取class属性
div_text01 = div_element.text#获取div标签间的文本,文本不包括子标签的文本
div_text02 = div_element.xpath("string(.)")#获取div标签间的文本,文本还包括子标签的文本

lxml获取元素文本属性的语法与Beautifulsoup有所区别,而获取其他属性的语法是一致的。

参考文档

beautifulsoup 根据class属性查找标签的方法
beautifulsoup怎么查找子元素?与抓取活动行页面数据
爬虫(三)—— BeautifulSoup模块获取元素
【爬虫】lxml的使用(xpath选择器、获取文本内容、获取属性、string(.))

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐