我们通过Requests请求url获取数据请求数据返回来之后就要提取目标数据,不同的网站返回的内容通常有多种不同的格式,一种是 json 格式我们可以直接通过json.loads转换pythonjson对象处理。另一种 XML 格式的,还有一种最常见格式的是 HTML 文档今天就来讲讲如何从 HTML 中提取感兴趣数据

BeautifulSoup一个用于解析 HTML 文档的 Python 库,通过 BeautifulSoup,你只需要用很少的代码可以提取出 HTML 中任何感兴趣内容,此外,它还有一定的 HTML 容错能力,对于一个格式不完整的HTML 文档,它也可以正确处理

安装 beautifulsoup

pip install beautifulsoup4

初始化对象可以直接传递字符串或者文件句柄

soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</html>")

支持多种解析接口

# python内置HTML解析
BeautifulSoup(markup, "html.parser")
# lxml语言支持HTML解析
BeautifulSoup(markup, "lxml")
# 解析XML引擎
BeautifulSoup(markup, "xml")
# 解析HTML5引擎
BeautifulSoup(markup, "html5lib")

自动添加补全标签

下面是一段不规范html,缺少闭合标签

html_doc = """
&lt;html&gt;<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" 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_doc, 'html.parser')
print(soup.prettify())

prettify()标准缩进格式的输出输出内容如下

 <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 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="link2">
     Tillie
    </a>
    ; and they lived at the bottom of a well.
  </p>
   <p class="story">
    ...
   </p>
  </body>
 </html>

bs4获取标签及内容示例


# title标签
soup.title
# <title>The Dormouse's story</title>

# title标签名称
soup.title.name
# 'title'

# # title标签的文本字符内容
soup.title.string
# 'The Dormouse's story'

# title标签父节点名称
soup.title.parent.name
# 'head'

# 从前向后找到html孙节点第一个p节点
soup.p
# <p class="title"><b>The Dormouse's story</b></p>

# p节点的class属性
soup.p['class']
# ['title']

# 进栈出栈方式找到第一个a标签
soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

# p节点的href属性
soup.a["href"]
# 'http://example.com/elsie'

soup.find_all('a')
# 同上
soup.find_all("p")[1].find_all("a")

# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.find(id="link3")
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>

遍历文档

从根节点 html 标签开始遍历元素进栈出栈,直到找到目标元素为止。

BeatifulSoup 将 HTML 抽象成为 4 类主要的数据类型:


type(soup)
# <class 'bs4.BeautifulSoup'>
type(soup.p)
# <class 'bs4.element.Tag'>
# type(soup.p.string)
<class 'bs4.element.NavigableString'>

Tag标签

每个 Tag 都有一个名字,它对应 HTML 的标签名称。

soup.p.name
# 'p'

标签有属性,属性的访问方式字典是类似的,它返回一个列表对象字符串

soup.p['class']
# ['title']

soup.a['href']
# 'http://example.com/elsie'

NavigableString
获取标签中的内容,直接使用 .stirng 即可获取,它是一个 NavigableString 对象

soup.p.string
# "The Dormouse's story"
type(soup.p.string)
bs4.element.NavigableString

搜索文档

搜索文档树是通过指定签名搜索元素,还可以通过指定标签的属性值来精确定位某个节点元素,最常用两个方法就是 findfind_all。这两个方法在 BeatifulSoup 和 Tag 对象上都可以调用

find_all()方法

find_all( name , attrs , recursive , text , **kwargs )

第一个参数 name 是标签节点的名字

# 所有p标签
soup.find_all("p")

# [<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 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>]

第二个参数是标签的class属性值

soup.find_all("p","title")
# 同上
soup.find_all("p",class_ ="title")

# [<p class="title"><b>The Dormouse's story</b></p>]

kwargs 是标签的属性名值对。

import re
# 支持使用标签属性
soup.find_all(href="http://example.com/lacie")
soup.find_all(id="link2")

# 支持使用正则
soup.find_all(href=re.compile("lacie"))
 
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

# 支持使用布尔类型
soup.find_all('a',id=True)

遍历搜索结合,先定位body 标签,再从 body 中找 a 标签.。

soup.body.find_all('a',id=True)

find()方法

find 方法跟 find_all 类似,唯一不同的地方是,它返回的单个 Tag 对象而非列表,如果没找到匹配的节点则返回 None。如果匹配多个 Tag,只返回第0个。

soup.body.find("a")
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

get_text()方法
获取标签里面内容,除了可以使用 .string 之外,还可以使用 get_text 方法,不同的地方在于前者返回的一个 NavigableString 对象,后者返回的是 字符串。

soup.body.find("a").get_text()
# Elsie

实际场景我们一般使用 get_text 方法获取标签中的内容

总结

通过beautifulsoup我们能够解析大部分静态html网页遍历和搜索组合方式定位html的标签,并获取相应标签的内容。

在这里插入图片描述

原文地址:https://blog.csdn.net/qq_22941289/article/details/134778039

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_41920.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注