1.概述:
BeautifulSoup库可以对HTMLH和XML格式进行解析,并提取其中的相关信息,可以用它来方便地提取网页中的信息。
BeautifulSoup库更多信息可以在官方文档。
通过pip install beautifulsoup4
命令安装BeautifulSoup库。
2.BeautifulSoup库解析器比较:
不同的解析器对相同html标签会做出不同解释,这里看个官方文档的例子:
from bs4 import BeautifulSoup
# lxml
print(BeautifulSoup("<a></p>", "lxml"))
print('------------')
# html5lib
print(BeautifulSoup("<a></p>", "html5lib"))
print('------------')
# html.parser
print(BeautifulSoup("<a></p>", "html.parser"))
运行结果如下:
<html><body><a></a></body></html>
------------
<html><head></head><body><a><p></p></a></body></html>
------------
<a></a>
官方文档推荐使用lxml
和html5lib
解析器,因为默认的html.parser
自动补全标签的功能很差,经常会出问题。
需要注意的是,要使用lxml
解析器,需要额外安装lxml
库。
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
bs4的HTML解析器 | BeautifulSoup(markup,”html.parser”) | python内置标准库,执行能力适中,文档纠错能力强 | 对python2.7.3以前版本容错能力差 |
lxml的HTML解析器 | BeautifulSoup(markup,”lxml”) | 速度快,文档纠错能力强 | 需要安装C语言库(pip install lxml) |
lxml的XML解析器 | BeautifulSoup(markup, “lxml-xml”) BeautifulSoup(markup,”xml”) | 速度快,唯一支持解析xml的解析器 | 需要安装C语言库(pip install xml) |
html5lib的解析器 | BeautifulSoup(markup, “html5lib”) | 最好的容错性,以浏览器的方式解析文档,生成html5格式 | 速度慢,但是不依赖外部库(pip install html5lib) |
3.简单使用:
将html传递给BeautifulSoup对象,然后给出一个解析器,即可对html解析。
首先截取一段BeautifulSoup库官网的网页源代码作为参数传递给BeautifulSoup对象,这里选择的解析器类型为lxml
。然后通过prettify()
方法,将要解析的内容以标准的格式进行输出。
html = """
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Beautiful Soup: We called him Tortoise because he taught us.</title>
<link rev="made" href="mailto:leonardr@segfault.org">
<link rel="stylesheet" type="text/css" href="/nb/themes/Default/nb.css">
<meta name="Description" content="Beautiful Soup: a library designed for screen-scraping HTML and XML.">
<meta name="generator" content="Markov Approximation 1.4 (module: leonardr)">
<meta name="author" content="Leonard Richardson">
</head>
<body bgcolor="white" text="black" link="blue" vlink="660066" alink="red">
<img align="right" src="10.1.jpg" width="250"><br />
<p>You didn't write that awful page. You're just trying to get some
data out of it. Beautiful Soup is here to help. Since 2004, it's been
saving programmers hours or days of work on quick-turnaround
screen scraping projects.</p>
<div align="center">
<a href="bs4/download/"><h1>Beautiful Soup</h1></a>
<p>"A tremendous boon." -- Python411 Podcast</p>
<p>[ <a href="#Download">Download</a> | <a
href="bs4/doc/">Documentation</a> | <a href="#HallOfFame">Hall of Fame</a> | <a href="https://code.launchpad.net/beautifulsoup">Source</a> | <a href="https://bazaar.launchpad.net/%7Eleonardr/beautifulsoup/bs4/view/head:/NEWS.txt">Changelog</a> | <a href="https://groups.google.com/forum/?fromgroups#!forum/beautifulsoup">Discussion group</a> | <a href="zine/">Zine</a> ]</p>
<p><small>If you use Beautiful Soup as part of your work, please consider a <a href="https://tidelift.com/subscription/pkg/pypi-beautifulsoup4?utm_source=pypi-beautifulsoup4&utm_medium=referral&utm_campaign=website">Tidelift subscription</a>. This will support many of the free software projects your organization depends on, not just Beautiful Soup.
<p>If Beautiful Soup is useful to you on a personal level, you might like to read <a href="zine/"><i>Tool Safety</i></a>, a short zine I wrote about what I learned about software development from working on Beautiful Soup. Thanks!</small></p>
</div>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
print(soup.title.string)
运行结果如下:
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<title>
Beautiful Soup: We called him Tortoise because he taught us.
</title>
<link href="mailto:leonardr@segfault.org" rev="made"/>
<link href="/nb/themes/Default/nb.css" rel="stylesheet" type="text/css"/>
<meta content="Beautiful Soup: a library designed for screen-scraping HTML and XML." name="Description"/>
<meta content="Markov Approximation 1.4 (module: leonardr)" name="generator"/>
<meta content="Leonard Richardson" name="author"/>
</head>
<body alink="red" bgcolor="white" link="blue" text="black" vlink="660066">
<img align="right" src="10.1.jpg" width="250"/>
<br/>
<p>
You didn't write that awful page. You're just trying to get some
data out of it. Beautiful Soup is here to help. Since 2004, it's been
saving programmers hours or days of work on quick-turnaround
screen scraping projects.
</p>
<div align="center">
<a href="bs4/download/">
<h1>
Beautiful Soup
</h1>
</a>
<p>
"A tremendous boon." -- Python411 Podcast
</p>
<p>
[
<a href="#Download">
Download
</a>
|
<a href="bs4/doc/">
Documentation
</a>
|
<a href="#HallOfFame">
Hall of Fame
</a>
|
<a href="https://code.launchpad.net/beautifulsoup">
Source
</a>
|
<a href="https://bazaar.launchpad.net/%7Eleonardr/beautifulsoup/bs4/view/head:/NEWS.txt">
Changelog
</a>
|
<a href="https://groups.google.com/forum/?fromgroups#!forum/beautifulsoup">
Discussion group
</a>
|
<a href="zine/">
Zine
</a>
]
</p>
<p>
<small>
If you use Beautiful Soup as part of your work, please consider a
<a href="https://tidelift.com/subscription/pkg/pypi-beautifulsoup4?utm_source=pypi-beautifulsoup4&utm_medium=referral&utm_campaign=website">
Tidelift subscription
</a>
. This will support many of the free software projects your organization depends on, not just Beautiful Soup.
</small>
</p>
<p>
If Beautiful Soup is useful to you on a personal level, you might like to read
<a href="zine/">
<i>
Tool Safety
</i>
</a>
, a short zine I wrote about what I learned about software development from working on Beautiful Soup. Thanks!
</p>
</div>
</body>
</html>
----------
Beautiful Soup: We called him Tortoise because he taught us.
最后观察输出的内容的开头和结尾里面包括了html、body
标签,也就是说lxml
解析器对于不标准的HTML字符串可以自动改正格式,这一步不是prettify()
方法处理的,而是在初始化BeautifulSoup时就完成了。
4.提取信息:
4.1 节点选择器
当网站节点结构非常清晰时,可以直接调用节点名称的方式(即选择节点)来解析。
需要注意的是,当有多个节点时,该选择方式只会返回选择到的第一个匹配的节点,后面的节点都会忽略。
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister link_class" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print('----------')
print(soup.p)
print(type(soup.p))
运行结果如下:
<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
----------
<p class="title"><b>The Dormouse's story</b></p>
<class 'bs4.element.Tag'>
通过打印结果类型,可以看到BeautifulSoup中经过选择器选择的结果都是Tag
类型,Tag
具有一些属性,直接调用属性可以提取节点信息。
基本元素 | 说明 |
---|---|
Tag | 标签,最基本的信息组织单元,分别用<> 和</> 标明开头和结尾 |
Name | 标签的名字,<p>...</p> 的名字是'p' ,格式:<tag>.name |
Attributs | 标签的属性,字典形式组织,格式:<tag>.attrs |
NavigableString | 标签内非属性字符串,<p>...</p> 中字符串,格式:<tag>.string |
Comment | 标签内字符串的注释部分,一种特殊的Comment类型 |
- 调用
name
属性获取标签名称
soup = BeautifulSoup(html, 'lxml')
print(soup.title.name)
运行结果如下:
title
- 调用
attrs
属性获取标签属性
一个节点可能有多个属性,例如id
、class
等,调用attrs
属性可以获取该节点的所有属性,返回结果为所有属性和属性值组成的字典。
需要注意的是,当属性的值是唯一时,返回的结果为单个字符串;当属性的值可能包含多个时,返回的结果为列表。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.a.attrs)
运行结果如下:
{'href': 'http://example.com/elsie', 'class': ['sister', 'link_class'], 'id': 'link1'}
要想获取某个属性的值,相当于获取字典中的某个键值。
print(soup.a.attrs['id']) # 返回结果为link1
也可以直接在节点元素后加中括号,传入属性名获取。
print(soup.a['id']) # 返回结果为link1
- 调用
string
属性获取标签内非属性字符串
print(soup.title.string) # 返回结果为The Dormouse's story
- 嵌套选择
对Tag
类型进行嵌套选择,返回的结果仍然是Tag
类型,可以使用上述属性,获取相应内容。
soup = BeautifulSoup(html, 'lxml')
print(soup.head)
print(type(soup.head))
print('------')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)
运行结果如下:
<head><title>The Dormouse's story</title></head>
<class 'bs4.element.Tag'>
------
<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story
4.2 关联选择
关联选择就是通过对标签树的遍历,以一个节点为基准,获取其子孙节点、父节点以及兄弟节点等,是提取HTML页面信息的重要手段和途径。
4.2.1 标签树的下行遍历
属性 | 说明 |
---|---|
.contents | 子节点的列表,将<tag> 所有儿子节点存入列表 |
.chlidren | 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点 |
.descendants | 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历 |
以如下html为例:
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="story">
here were three little sisters
<a href="#1" class="link1" id="link1">
<p>Elsie</p>
</a>
<a href="#2" class="link2" id="link2">
<p>Lacie</p>
</a>
<a href="#3" class="link3" id="link3">
<p>Tillie</p>
</a>
</p>
<p class="story">others</p>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
contents
属性
print(soup.p.contents)
运行结果如下:
['\n here were three little sisters\n ', <a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>, '\n', <a class="link2" href="#2" id="link2">
<p>Lacie</p>
</a>, '\n', <a class="link3" href="#3" id="link3">
<p>Tillie</p>
</a>, '\n']
可以看出,contents
属性返回结果为所有直接子节点组成的列表。
chlidren
属性
print(type(soup.p.children))
for i , child in enumerate(soup.p.children):
print(f'第{i}个子节点:' , child)
运行结果如下:
<class 'list_iterator'>
第0个子节点:
here were three little sisters
第1个子节点: <a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
第2个子节点:
第3个子节点: <a class="link2" href="#2" id="link2">
<p>Lacie</p>
</a>
第4个子节点:
第5个子节点: <a class="link3" href="#3" id="link3">
<p>Tillie</p>
</a>
第6个子节点:
chlidren
属性返回结果为生成器类型,可以通过for循环输出对应内容。
descendants
属性
print(type(soup.p.descendants))
for i , descendant in enumerate(soup.p.descendants):
print(f'第{i}个子孙节点:' , descendant)
运行结果如下:
<class 'generator'>
第0个子孙节点:
here were three little sisters
第1个子孙节点: <a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
第2个子孙节点:
第3个子孙节点: <p>Elsie</p>
第4个子孙节点: Elsie
第5个子孙节点:
第6个子孙节点:
第7个子孙节点: <a class="link2" href="#2" id="link2">
<p>Lacie</p>
</a>
第8个子孙节点:
第9个子孙节点: <p>Lacie</p>
第10个子孙节点: Lacie
第11个子孙节点:
第12个子孙节点:
第13个子孙节点: <a class="link3" href="#3" id="link3">
<p>Tillie</p>
</a>
第14个子孙节点:
第15个子孙节点: <p>Tillie</p>
第16个子孙节点: Tillie
第17个子孙节点:
第18个子孙节点:
descendants
属性返回结果为生成器类型,可以通过for循环输出对应内容。不同的是,descendants
属性会获取所有子孙节点。
4.2.2 标签树的上行遍历
属性 | 说明 |
---|---|
.parent | 节点的父亲标签 |
.parents | 节点先辈标签的迭代类型,用于循环遍历先辈节点 |
以如下html为例:
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<div class="story">
<a href="#1" class="link1" id="link1">
<p>Elsie</p>
</a>
</div>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
parent
属性
调用parent
属性,可以获取某个节点的直接父节点。
print(soup.p.parent)
运行结果如下:
<a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
parents
属性
调用parents
属性,可以获取某个节点的所有祖先节点。返回结果为生成器类型,可以通过for循环输出对应内容。
print(type(soup.p.parents))
for i , parent in enumerate(soup.p.parents):
print(f'第{i}个祖先节点:' , parent)
运行结果如下:
<class 'generator'>
第0个祖先节点: <a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
第1个祖先节点: <div class="story">
<a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
</div>
第2个祖先节点: <body>
<div class="story">
<a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
</div>
</body>
第3个祖先节点: <html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<div class="story">
<a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
</div>
</body>
</html>
第4个祖先节点: <html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<div class="story">
<a class="link1" href="#1" id="link1">
<p>Elsie</p>
</a>
</div>
</body>
</html>
4.2.3 标签树的平行遍历
属性 | 说明 |
---|---|
.next_sibling | 返回按照HTML文本顺序的下一个平行节点标签 |
.previous_sibling | 返回按照HTML文本顺序的上一个平行节点标签 |
.next_siblings | 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签 |
.previous_siblings | 迭代类型,返回按照HTML文本顺序的前续所有的平行节点标签 |
这里需要注意的是,平行遍历只能发生在同一父节点下的各个节点之间。
以如下html为例:
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="story">
<p>Dormouse</p>
Elsie
<a href="#1" class="link1" id="link1"></a>
Lacie
<a href="#2" class="link2" id="link2"></a>
Tillie
<a href="#3" class="link3" id="link3"></a>
</p>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
next_sibling
属性和previous_sibling
属性
调用next_sibling
属性获取某节点的下一个兄弟节点。
调用previous_sibling
属性某节点的上一个兄弟节点。
print('下一个兄弟节点:' , soup.a.next_sibling)
print('-------')
print('上一个兄弟节点:' , soup.a.previous_sibling)
运行结果如下:
下一个兄弟节点:
Lacie
-------
上一个兄弟节点:
Elsie
next_siblings
属性和previous_siblings
属性
调用next_siblings
属性获取某节点后面的所有兄弟节点。返回结果为生成器类型,可以通过for循环输出对应内容。
调用previous_siblings
属性某节点前面的所有兄弟节点。返回结果为生成器类型,可以通过for循环输出对应内容。
print(type(soup.a.next_siblings))
for i , sibling in enumerate(soup.a.next_siblings):
print(f'该节点后面第{i}个兄弟节点:' , sibling)
print('-------')
print(type(soup.a.previous_siblings))
for i , sibling in enumerate(soup.a.previous_siblings):
print(f'该节点前面第{i}个兄弟节点:' , sibling)
运行结果如下:
<class 'generator'>
该节点后面第0个兄弟节点:
Lacie
该节点后面第1个兄弟节点: <a class="link2" href="#2" id="link2"></a>
该节点后面第2个兄弟节点:
Tillie
该节点后面第3个兄弟节点: <a class="link3" href="#3" id="link3"></a>
该节点后面第4个兄弟节点:
-------
<class 'generator'>
该节点前面第0个兄弟节点:
Elsie
该节点前面第1个兄弟节点: <p>Dormouse</p>
该节点前面第2个兄弟节点: <p class="story">
</p>
该节点前面第3个兄弟节点:
4.3 方法选择器
前面的几种选择方法均为基于属性的选择,但是在进行比较复杂的选择时,会变得较繁琐、不够灵活。
BeautifulSoup库提供了一些查询方法进行灵活查询。
以如下html为例:
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<div class="story">
<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>
<ul class="list list_active" id="list_2">
<li class="list_element">EEE</li>
<li class="list_element">FFF</li>
</ul>
</div>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
4.3.1 find_all()方法
提供向find_all()
方法传递响应参数,可以查询所有符合条件的元素,API如下:
find_all(name , attrs , recursive , text , **kwargs)
name
参数
根据节点名查询。
# 查询所有ul节点
print(type(soup.find_all(name='ul')))
print(soup.find_all(name='ul'))
运行结果如下:
<class 'bs4.element.ResultSet'>
[<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>, <ul class="list list_active" id="list_2">
<li class="list_element">EEE</li>
<li class="list_element">FFF</li>
</ul>]
可以看出,返回结果中每个元素均为Tag
类型,因此可以进行嵌套查询。
for ul in soup.find_all(name='ul'):
print(ul.find_all(name='li'))
print(type(ul.find_all(name='li')[0]))
运行结果如下:
[<li class="list_element">AAA</li>, <li class="list_element">BBB</li>]
<class 'bs4.element.Tag'>
[<li class="list_element">EEE</li>, <li class="list_element">FFF</li>]
<class 'bs4.element.Tag'>
可以看出,返回的结果仍然是列表类型,列表中的每个元素仍然是Tag
类型。因此可以再依次遍历每个li节点,提取文本信息。
for ul in soup.find_all(name='ul'):
for li in ul.find_all(name='li'):
print(li.string)
运行结果如下:
AAA
BBB
EEE
FFF
attrs
参数
根据属性查询。传入的attrs
参数为字典类型。
print(soup.find_all(attrs={'id':'list_1'}))
print('------')
print(soup.find_all(attrs={'name':'elements'}))
print('------')
print(soup.find_all(attrs={'class':'list'}))
运行结果如下:
[<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>]
------
[<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>]
------
[<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>, <ul class="list list_active" id="list_2">
<li class="list_element">EEE</li>
<li class="list_element">FFF</li>
</ul>]
对于一些常用的属性,例如id
、class
可以不通过attrs
参数传递,直接传入id
、class_
(需要注意的是,class
在Python中为关键字,因此需要使用class_
)参数。
print(soup.find_all(id='list_1'))
print('------')
print(soup.find_all(class_='list'))
运行结果如下:
[<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>]
------
[<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>, <ul class="list list_active" id="list_2">
<li class="list_element">EEE</li>
<li class="list_element">FFF</li>
</ul>]
text
参数
text
参数可以用来匹配节点的文本,传入形式可以是字符串,也可以是正则表达式对象。返回的结果为匹配的节点文本组成的列表
import re
print(soup.find_all(text='AAA'))
print('-----------')
print(soup.find_all(text=re.compile(r'[A-Z]+')))
运行结果如下:
['AAA']
-----------
["The Dormouse's story", 'AAA', 'BBB', 'EEE', 'FFF']
4.3.2 find()方法
与find_all()
方法不同,find()
方法返回的是单个元素,即第一个匹配到的元素。
print(soup.find(name='ul'))
print('-----------')
print(soup.find(attrs={'id':'list_1'}))
print('-----------')
print(soup.find(text='AAA'))
运行结果如下:
<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>
-----------
<ul class="list" id="list_1" name="elements">
<li class="list_element">AAA</li>
<li class="list_element">BBB</li>
</ul>
-----------
AAA
此外,还有一些查询方法,与find()
方法、find_all()
方法用法相同。
查询方法 | 说明 |
---|---|
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.4 CSS选择器
使用BeautifulSoup提供的CSS选择器,只需要调用select()
方法,传入相应的CSS选择器即可。
以如下html为例:
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<div class="story">
<ul class="list" id="list_1" name="elements">
<li class="list_element_1">AAA</li>
<li class="list_element_1">BBB</li>
</ul>
<ul class="list list_active" id="list_2">
<li class="list_element_2">EEE</li>
<li class="list_element_2">FFF</li>
</ul>
</div>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
- 选择:
print(soup.select('ul li'))
print('-----------')
print(soup.select('#list_1 .list_element_1'))
print('-----------')
print(soup.select('.story .list_active'))
运行结果如下:
[<li class="list_element_1">AAA</li>, <li class="list_element_1">BBB</li>, <li class="list_element_2">EEE</li>, <li class="list_element_2">FFF</li>]
-----------
[<li class="list_element_1">AAA</li>, <li class="list_element_1">BBB</li>]
-----------
[<ul class="list list_active" id="list_2">
<li class="list_element_2">EEE</li>
<li class="list_element_2">FFF</li>
</ul>]
- 嵌套选择:
for ul in soup.select('ul'):
print(ul.select('li'))
运行结果如下:
[<li class="list_element_1">AAA</li>, <li class="list_element_1">BBB</li>]
[<li class="list_element_2">EEE</li>, <li class="list_element_2">FFF</li>]
- 获取属性:
返回的结果为Tag
类型,因此可以使用之前介绍的方法获取节点属性。
for ul in soup.select('ul'):
for li in ul.select('li'):
print(li.attrs['class'])
print('--------')
运行结果如下:
['list_element_1']
--------
['list_element_1']
--------
['list_element_2']
--------
['list_element_2']
--------
- 获取文本:
可以使用string
属性获取节点文本信息,也可以使用get_text()
方法来获取。
for li in soup.select('li'):
print(li.string)
print(li.get_text())
print('--------')
运行结果如下:
AAA
AAA
--------
BBB
BBB
--------
EEE
EEE
--------
FFF
FFF
--------