首页Python5.解析库——Beauti...

5.解析库——BeautifulSoup库

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>

官方文档推荐使用lxmlhtml5lib解析器,因为默认的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属性获取标签属性

一个节点可能有多个属性,例如idclass等,调用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>]

对于一些常用的属性,例如idclass可以不通过attrs参数传递,直接传入idclass_(需要注意的是,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
--------
RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments