使用Beautiful Soup来解析网页数据

阅读指导:
这篇文章详细讲解了Beautiful Soup解析的方法。每个方法都配有相应的代码示例,读者可以通过本文更深入地了解Beautiful Soup。由于文章篇幅较长,建议通过目录选择您感兴趣的部分进行学习。

2. Beautiful Soup

Beautiful Soup提供了简单易用的 API 来导航、搜索和修改解析树。Beautiful Soup 通过将复杂的 HTML 文档转换为一个树形结构,使得解析和操作 HTML 内容变得更加方便。

其优点是:

  • 强大的文档解析能力
  • 多种解析器支持
  • 灵活的节点搜索和导航功能

2.1 初步使用

使用实例:

<!--假设这是某个网页页面的页面代码,页面链接为 URL -->
<html><head><title>The Dormouse's story</title></head>
<body>
	<p class="title" name="dromouse"><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" 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
import requests
url = "URL"
html= requests.get(url)
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
print(soup.title.string)

输出:

<html>
 <head>
  <title>
   The Dormouse's story
  </title>
 </head>
 <body>
  <p class="title" name="dromouse">
   <b>
    The Dormouse's story
   </b>
  </p>
  <p class="story">
   Once upon a time there were three little sisters; and their names were
   <a class="sister" href="http://example.com/elsie" id="link1">
    <!-- Elsie -->
   </a>
   ,
   <a class="sister" href="http://example.com/lacie" id="link2">
    Lacie
   </a>
   and
   <a class="sister" href="http://example.com/tillie" id="link3">
    Tillie
   </a>
   ;
and they lived at the bottom of a well.
  </p>
  <p class="story">
   ...
  </p>
 </body>
</html>

The Dormouse's story

代码解释:
soup.prettify()该方法,将要解析的字符串以标准的缩进格式输出。
soup.title.string通过string属性,输出title标签里面的文字

2.2 节点选择器

       使用 . 的方式依次按层级的向下访问,当出现有同样多个节点的时候,只会匹配到第一个节点而忽略后面的结点。

例:

<!--./html-->
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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" 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(soup.title.string)
print(soup.head)
print(soup.p)

输出:

<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story
<head><title>The Dormouse's story</title></head>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>

输出解释:
<class ‘bs4.element.Tag’>这个类型是Beautiful Soup中一个很重要的数据结构,经过选择器的选择后,都是这种Tag类型,并且里面有很多属性也是很常用的,比如strig等。

 
 
以下的对数据的获取方式,都是基于<class ‘bs4.element.Tag’>这个Tag类型开展的。

2.2.1 节点选择器获取名称

利用name属性来获取节点的名称
注意:这个名称是标签名

例:

<!--html-->
<html><head><title>The Dormouse's story</title></head>

获取代码:

print(soup.title.name)

输出:

title

2.2.2 节点选择器获取属性

利用attars来获取一个元素的属性

返回的是一个字典,并且键值对里面的值部分,要注意其数据类型

例:

<!--./html-->
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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" 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.p.attrs)
print(soup.p.attrs["name"])
print(soup.p.attrs["class"])

输出:

{'class': ['title'], 'name': 'dromouse'}
dromouse
['title']

2.2.3 节点选择器获取内容

使用string属性来获取元素的内容

例:

<!--html-->
<html><head><title>The Dormouse's story</title></head>

获取代码:

soup = BeautifulSoup(html, 'lxml')
print(soup.title.string)

输出:

The Dormouse's story

2.2.4 节点选择器的嵌套选择

使用 . 来对Tag类型的对象继续向下做进一步的选择或处理

<!--html-->
<html><head><title>The Dormouse's story</title></head>
<body>

获取代码:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)

输出:

<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story

2.3 方法选择器

find_all查询所有符合条件的元素
基本语法:
find_all(name, attrs, recursive, text, **kwarge)

 

下面进行深度讲解:

2.3.1 方法选择器获取名称

使用name属性来获取

例:

<!--html-->
<div class="panel">
    <div class="panel-heading">
        <h4>Hello</h4>
    </div>
    <div class="panel-body">
        <ul class="list" id="list-1">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
            <li class="element">Jay</li>
        </ul>
        <ul class="list list-small" id="list-2">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
        </ul>
    </div>
</div>

获取代码:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(name='ul'))
print()
print(type(soup.find_all(name='ul')[0]))
print()
for ul in soup.find_all(name='ul'):
    print(ul.find_all(name='li'))
print()
for ul in soup.find_all(name='ul'):
    print(ul.find_all(name='li'))
    for li in ul.find_all(name='li'):
        print(li.string)

输出:

[<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>, <ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>]

<class 'bs4.element.Tag'>

[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]

[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
Foo
Bar
Jay
[<li class="element">Foo</li>, <li class="element">Bar</li>]
Foo
Bar

2.3.2 方法选择器获取属性

第一种:使用attrs来对节点的属性进行查询,这是比较普遍使用的方式

例:
获取 id 属性值为 “list-1” 和 name 属性为 “eLements” 的节点

<!--html-->
<div class="panel">
    <div class="panel-heading">
        <h4>Hello</h4>
    </div>
    <div class="panel-body">
        <ul class="list" id="list-1" name="elements">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
            <li class="element">Jay</li>
        </ul>
        <ul class="list list-small" id="list-2">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
        </ul>
    </div>
</div>

获取代码:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(attrs={'id': 'list-1'}))
print()
print(soup.find_all(attrs={'name': 'elements'}))
print()

输出:

[<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]

[<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]

第二种:对于class,id这种常用属性,可以直接使用

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(id='list-1'))
print()
print(soup.find_all(class_='element'))

输出:

[<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]

[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]

2.3.3 方法选择器获取内容

在find_all中使用 string 参数,对 string 赋值为正则表达式来获取元素的文字,不要用text参数,这个已经被废除

例:

<!--html-->
<div class="panel">
    <div class="panel-body">
        <a>Hello, this is a link</a>
        <a>Hello, this is a link, too</a>
    </div>
</div>

获取代码:

import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(string=re.compile("link")))

输出:

['Hello, this is a link', 'Hello, this is a link, too']

2.3.4 查询第一个符合的元素

采用 find方式 ,这与find_all的获取数据的方式相同,只是范围不同罢了,find只查询符合条件的第一个元素。

2.4 css选择器

使用select方式获取元素,其获取数据的方式也find_all类似

例:
我们要使用 CSS 选择器来提取所有链接和列表项

<!--html-->
<html>
  <head>
    <title>Example Page</title>
  </head>
  <body>
    <div class="panel">
      <div class="panel-body">
        <a href="http://example.com/link1" class="link">Link 1</a>
        <a href="http://example.com/link2" class="link">Link 2</a>
      </div>
    </div>
    <ul id="list">
      <li class="item">Item 1</li>
      <li class="item">Item 2</li>
      <li class="item">Item 3</li>
    </ul>
  </body>
</html>

获取代码:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')

# 使用 CSS 选择器选择所有链接
links = soup.select('a.link')
for link in links:
    print(link.get_text(), link['href'])

# 使用 CSS 选择器选择所有列表项
items = soup.select('ul#list li.item')
for item in items:
    print(item.get_text())

输出:

Link 1 http://example.com/link1
Link 2 http://example.com/link2
Item 1
Item 2
Item 3

代码解释:

  • soup.select(‘a.link’):选择所有带有class=“link” 的 < a > 标签。
  • link.get_text():获取链接文本。
  • link[‘href’]:获取链接的 href 属性值。
  • soup.select(‘ul#list li.item’):选择
    • 标签中带有 id=“list” 的所有

    • 标签,并且这些
    • 标签带有 class=“item”。

常见的css选择器

表示描述例子
tag选择所有指定标签的元素。例如:div。
.class选择所有指定类的元素。例如:.panel-body。
#id选择所有指定 ID 的元素。例如:#list。
tag.class选择指定标签且带有指定类的元素。例如:a.link。
tag#id选择指定标签且带有指定 ID 的元素。例如:ul#list。
tag[attr=value]选择指定标签且带有指定属性值的元素。例如:a[href=“http://example.com/link1”]。
parent > child选择所有指定父标签的直接子标签。例如:div > a。
ancestor descendant选择所有指定祖先标签的后代标签。例如:div a。
  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值