Python下利用BeautifulSoup解析HTML的实现

摘要

Beautiful Soup 是一个可以从 HTML 或 XML 格式文件中提取数据的 Python 库,他可以将HTML 或 XML 数据解析为Python 对象,以方便通过Python代码进行处理。

文档环境

  • Centos7.5
  • Python2.7
  • BeautifulSoup4

Beautifu Soup 使用说明

Beautiful Soup 的基本功能就是对HTML的标签进行查找及编辑。

基本概念-对象类型

Beautiful Soup 将复杂 HTML 文档转换成一个复杂的树形结构,每个节点都被转换成一个Python 对象,Beautiful Soup将这些对象定义了4 种类型: Tag、NavigableString、BeautifulSoup、Comment 。

对象类型 描述
BeautifulSoup 文档的全部内容
Tag HTML的标签
NavigableString 标签包含的文字
Comment 是一种特殊的NavigableString类型,当标签中的NavigableString 被注释时,则定义为该类型

安装及引用

# Beautiful Soup
pip install bs4

# 解析器
pip install lxml
pip install html5lib
# 初始化
from bs4 import BeautifulSoup

# 方法一,直接打开文件
soup = BeautifulSoup(open("index.html"))

# 方法二,指定数据
resp = "<html>data</html>"
soup = BeautifulSoup(resp, 'lxml')

# soup 为 BeautifulSoup 类型对象
print(type(soup))

标签搜索及过滤

基本方法

标签搜索有find_all() 和find() 两个基本的搜索方法,find_all() 方法会返回所有匹配关键字的标签列表,find()方法则只返回一个匹配结果。

soup = BeautifulSoup(resp, 'lxml')

# 返回一个标签名为"a"的Tag
soup.find("a")

# 返回所有tag 列表
soup.find_all("a")

## find_all方法可被简写
soup("a")

#找出所有以b开头的标签
for tag in soup.find_all(re.compile("^b")):
  print(tag.name)

#找出列表中的所有标签
soup.find_all(["a", "p"])

# 查找标签名为p,class属性为"title"
soup.find_all("p", "title")

# 查找属性id为"link2"
soup.find_all(id="link2")

# 查找存在属性id的
soup.find_all(id=True)

#
soup.find_all(href=re.compile("elsie"), id='link1')

#
soup.find_all(attrs={"data-foo": "value"})

#查找标签文字包含"sisters"
soup.find(string=re.compile("sisters"))

# 获取指定数量的结果
soup.find_all("a", limit=2)

# 自定义匹配方法
def has_class_but_no_id(tag):
  return tag.has_attr('class') and not tag.has_attr('id')
soup.find_all(has_class_but_no_id)

# 仅对属性使用自定义匹配方法
def not_lacie(href):
    return href and not re.compile("lacie").search(href)
soup.find_all(href=not_lacie)

# 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False 

soup.find_all("title", recursive=False)

扩展方法

ind_parents() 所有父辈节点
find_parent() 第一个父辈节点
find_next_siblings() 之后的所有兄弟节点
find_next_sibling() 之后的第一个兄弟节点
find_previous_siblings() 之前的所有兄弟节点
find_previous_sibling() 之前的第一个兄弟节点
find_all_next() 之后的所有元素
find_next() 之后的第一个元素
find_all_previous() 之前的所有元素
find_previous() 之前的第一个元素

CSS选择器

Beautiful Soup支持大部分的CSS选择器 http://www.w3.org/TR/CSS2/selector.html, 在 Tag 或 BeautifulSoup 对象的 .select() 方法中传入字符串参数, 即可使用CSS选择器的语法找到tag。

html_doc = """
<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" rel="external nofollow" class="sister" id="link1">Elsie</a>,
  <a href="http://example.com/lacie" rel="external nofollow" class="sister" id="link2">Lacie</a>
  and
  <a href="http://example.com/tillie" rel="external nofollow" class="sister" id="link3">Tillie</a>;
  and they lived at the bottom of a well.
 </p>

 <p class="story">...</p>
"""

soup = BeautifulSoup(html_doc)

# 所有 a 标签
soup.select("a")

# 逐层查找
soup.select("body a")
soup.select("html head title")

# tag标签下的直接子标签
soup.select("head > title")
soup.select("p > #link1")

# 所有匹配标签之后的兄弟标签
soup.select("#link1 ~ .sister")

# 匹配标签之后的第一个兄弟标签
soup.select("#link1 + .sister")

# 根据calss类名
soup.select(".sister")
soup.select("[class~=sister]")

# 根据ID查找
soup.select("#link1")
soup.select("a#link1")

# 根据多个ID查找
soup.select("#link1,#link2")

# 根据属性查找
soup.select('a[href]')

# 根据属性值查找
soup.select('a[href^="http://example.com/"]')
soup.select('a[href$="tillie"]')
soup.select('a[href*=".com/el"]')

# 只获取一个匹配结果
soup.select(".sister", limit=1)

# 只获取一个匹配结果
soup.select_one(".sister")

标签对象方法

标签属性

soup = BeautifulSoup('<p class="body strikeout" id="1">Extremely bold</p><p class="body strikeout" id="2">Extremely bold2</p>')
# 获取所有的 p标签对象
tags = soup.find_all("p")
# 获取第一个p标签对象
tag = soup.p
# 输出标签类型
type(tag)
# 标签名
tag.name
# 标签属性
tag.attrs
# 标签属性class 的值
tag['class']
# 标签包含的文字内容,对象NavigableString 的内容
tag.string

# 返回标签内所有的文字内容
for string in tag.strings:
  print(repr(string))

# 返回标签内所有的文字内容, 并去掉空行
for string in tag.stripped_strings:
  print(repr(string))

# 获取到tag中包含的所有及包括子孙tag中的NavigableString内容,并以Unicode字符串格式输出
tag.get_text()
## 以"|"分隔
tag.get_text("|")
## 以"|"分隔,不输出空字符
tag.get_text("|", strip=True)
获取子节点
tag.contents # 返回第一层子节点的列表
tag.children # 返回第一层子节点的listiterator 对象
for child in tag.children:
  print(child)

tag.descendants # 递归返回所有子节点
for child in tag.descendants:
  print(child)

获取父节点

tag.parent # 返回第一层父节点标签
tag.parents # 递归得到元素的所有父辈节点

for parent in tag.parents:
  if parent is None:
    print(parent)
  else:
    print(parent.name)

获取兄弟节点

# 下一个兄弟元素
tag.next_sibling 

# 当前标签之后的所有兄弟元素
tag.next_siblings
for sibling in tag.next_siblings:
  print(repr(sibling))

# 上一个兄弟元素
tag.previous_sibling

# 当前标签之前的所有兄弟元素
tag.previous_siblings
for sibling in tag.previous_siblings:
  print(repr(sibling))

元素的遍历

Beautiful Soup中把每个tag定义为一个“element”,每个“element”,被自上而下的在HTML中排列,可以通过遍历命令逐个显示标签

# 当前标签的下一个元素
tag.next_element

# 当前标签之后的所有元素
for element in tag.next_elements:
  print(repr(element))

# 当前标签的前一个元素
tag.previous_element
# 当前标签之前的所有元素
for element in tag.previous_elements:
  print(repr(element))

修改标签属性

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b

tag.name = "blockquote"
tag['class'] = 'verybold'
tag['id'] = 1

tag.string = "New link text."
print(tag)

修改标签内容(NavigableString)

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
tag.string = "New link text."

添加标签内容(NavigableString)

soup = BeautifulSoup("<a>Foo</a>")
tag = soup.a
tag.append("Bar")
tag.contents

# 或者

new_string = NavigableString("Bar")
tag.append(new_string)
print(tag)

添加注释(Comment)

注释是一个特殊的NavigableString 对象,所以同样可以通过append() 方法进行添加。

from bs4 import Comment
soup = BeautifulSoup("<a>Foo</a>")
new_comment = soup.new_string("Nice to see you.", Comment)
tag.append(new_comment)
print(tag)

添加标签(Tag)

添加标签方法有两种,一种是在指定标签的内部添加(append方法),另一种是在指定位置添加(insert、insert_before、insert_after方法)

append方法

soup = BeautifulSoup("<b></b>")
tag = soup.b
new_tag = soup.new_tag("a", href="http://www.example.com" rel="external nofollow" )
new_tag.string = "Link text."
tag.append(new_tag)
print(tag)

* insert方法,是指在当前标签子节点列表的指定位置插入对象(Tag或NavigableString)

html = '<b><a href="http://example.com/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >I linked to <i>example.com</i></a></b>'
soup = BeautifulSoup(html)
tag = soup.a
tag.contents
tag.insert(1, "but did not endorse ")
tag.contents

insert_before() 和 insert_after() 方法则在当前标签之前或之后的兄弟节点添加元素

html = '<b><a href="http://example.com/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >I linked to <i>example.com</i></a></b>'
soup = BeautifulSoup(html)
tag = soup.new_tag("i")
tag.string = "Don't"
soup.b.insert_before(tag)
soup.b

* wrap() 和 unwrap()可以对指定的tag元素进行包装或解包,并返回包装后的结果。

```python
# 添加包装
soup = BeautifulSoup("<p>I wish I was bold.</p>")
soup.p.string.wrap(soup.new_tag("b"))
#输出 <b>I wish I was bold.</b>

soup.p.wrap(soup.new_tag("div"))
#输出 <div><p><b>I wish I was bold.</b></p></div>

# 拆解包装
markup = '<a href="http://example.com/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >I linked to <i>example.com</i></a>'
soup = BeautifulSoup(markup)
a_tag = soup.a

a_tag.i.unwrap()
a_tag
#输出 <a href="http://example.com/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >I linked to example.com</a>

删除标签

html = '<b><a href="http://example.com/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >I linked to <i>example.com</i></a></b>'
soup = BeautifulSoup(html)
# 清楚当前标签的所有子节点
soup.b.clear()

# 将当前标签及所有子节点从soup 中移除,返回当前标签。
b_tag=soup.b.extract()
b_tag
soup

# 将当前标签及所有子节点从soup 中移除,无返回。
soup.b.decompose()

# 将当前标签替换为指定的元素
tag=soup.i
new_tag = soup.new_tag("p")
new_tag.string = "Don't"
tag.replace_with(new_tag)

其他方法

输出

# 格式化输出
tag.prettify()
tag.prettify("latin-1")
  • 使用Beautiful Soup解析后,文档都被转换成了Unicode,特殊字符也被转换为Unicode,如果将文档转换成字符串,Unicode编码会被编码成UTF-8.这样就无法正确显示HTML特殊字符了
  • 使用Unicode时,Beautiful Soup还会智能的把“引号”转换成HTML或XML中的特殊字符

文档编码

使用Beautiful Soup解析后,文档都被转换成了Unicode,其使用了“编码自动检测”子库来识别当前文档编码并转换成Unicode编码。

soup = BeautifulSoup(html)
soup.original_encoding

# 也可以手动指定文档的编码
soup = BeautifulSoup(html, from_encoding="iso-8859-8")
soup.original_encoding

# 为提高“编码自动检测”的检测效率,也可以预先排除一些编码
soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])
通过Beautiful Soup输出文档时,不管输入文档是什么编码方式,默认输出编码均为UTF-8编码
文档解析器
Beautiful Soup目前支持, “lxml”, “html5lib”, 和 “html.parser”

soup=BeautifulSoup("<a><b /></a>")
soup
#输出: <html><body><a><b></b></a></body></html>
soup=BeautifulSoup("<a></p>", "lxml")
soup
#输出: <html><body><a></a></body></html>
soup=BeautifulSoup("<a></p>", "html5lib")
soup
#输出: <html><head></head><body><a><p></p></a></body></html>
soup=BeautifulSoup("<a></p>", "html.parser")
soup
#输出: <a></a>

参考文档
https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Python爬虫beautifulsoup4常用的解析方法总结

    摘要 如何用beautifulsoup4解析各种情况的网页 beautifulsoup4的使用 关于beautifulsoup4,官网已经讲的很详细了,我这里就把一些常用的解析方法做个总结,方便查阅. 装载html文档 使用beautifulsoup的第一步是把html文档装载到beautifulsoup中,使其形成一个beautifulsoup对象. import requests from bs4 import BeautifulSoup url = "http://new.qq.com/o

  • Python使用Beautiful Soup爬取豆瓣音乐排行榜过程解析

    前言 要想学好爬虫,必须把基础打扎实,之前发布了两篇文章,分别是使用XPATH和requests爬取网页,今天的文章是学习Beautiful Soup并通过一个例子来实现如何使用Beautiful Soup爬取网页. 什么是Beautiful Soup Beautiful Soup是一款高效的Python网页解析分析工具,可以用于解析HTL和XML文件并从中提取数据. Beautiful Soup输入文件的默认编码是Unicode,输出文件的编码是UTF-8. Beautiful Soup具有将

  • Python爬虫库BeautifulSoup的介绍与简单使用实例

    一.介绍 BeautifulSoup库是灵活又方便的网页解析库,处理高效,支持多种解析器.利用它不用编写正则表达式即可方便地实现网页信息的提取. Python常用解析库 解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库.执行速度适中 .文档容错能力强 Python 2.7.3 or 3.2.2)前的版本中文容错能力差 lxml HTML 解析器 BeautifulSoup(markup,

  • python使用BeautifulSoup与正则表达式爬取时光网不同地区top100电影并对比

    前言 还有一年多就要毕业了,不准备考研的我要着手准备找实习及工作了,所以一直没有更新. 因为Python是自学不久,发现很久不用的话以前学过的很多方法就忘了,今天打算使用简单的BeautifulSoup和一点正则表达式的方法来爬一下top100电影,当然,我们并不仅是使用爬虫爬取数据,这样的话,数据中存在很多的对人有用的信息则被忽略了.所以,爬取数据只是开头,对这些数据根据意愿进行分析,或许能有额外的收获. 注:本人还是Python菜鸟,若有错误欢迎指正 本次我们爬取时光网(http://www

  • python使用beautifulsoup4爬取酷狗音乐代码实例

    这篇文章主要介绍了python使用beautifulsoup4爬取酷狗音乐代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 小编经常在网上听一些音乐但是有一些网站好多音乐都是付费下载的正好我会点爬虫技术,空闲时间写了一份,截止4月底没有问题的,会下载到当前目录,只要按照bs4库就好, 安装方法:pip install beautifulsoup4 完整代码如下:双击就能直接运行 from bs4 import BeautifulSoup

  • Python获取基金网站网页内容、使用BeautifulSoup库分析html操作示例

    本文实例讲述了Python获取基金网站网页内容.使用BeautifulSoup库分析html操作.分享给大家供大家参考,具体如下: 利用 urllib包 获取网页内容 #引入包 from urllib.request import urlopen response = urlopen("http://fund.eastmoney.com/fund.html") html = response.read(); #这个网页编码是gb2312 #print(html.decode("

  • python3实现网络爬虫之BeautifulSoup使用详解

    这一次我们来了解一下美味的汤--BeautifulSoup,这将是我们以后经常使用的一个库,并且非常的好用. BeautifuleSoup库的名字取自刘易斯·卡罗尔在<爱丽丝梦游仙境>里的同名诗歌.在故事中,这首歌是素甲鱼唱的.就像它在仙境中的说法一样,BeautifulSoup尝试化平淡为神奇.它通过定位HTML标签来格式化和组织复杂的网络信息,用简单易用的Python对象为我们展现XML结构信息. 由于BeautifulSoup库不是Python标准库,因此我们需要单独安装这个库,才能使用

  • python爬虫开发之Beautiful Soup模块从安装到详细使用方法与实例

    python爬虫模块Beautiful Soup简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等功能.它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序.Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码.你不需要考虑编码方式,除非

  • Python爬虫实现使用beautifulSoup4爬取名言网功能案例

    本文实例讲述了Python爬虫实现使用beautifulSoup4爬取名言网功能.分享给大家供大家参考,具体如下: 爬取名言网top10标签对应的名言,并存储到mysql中,字段(名言,作者,标签) #! /usr/bin/python3 # -*- coding:utf-8 -*- from urllib.request import urlopen as open from bs4 import BeautifulSoup import re import pymysql def find_

  • Python基于BeautifulSoup和requests实现的爬虫功能示例

    本文实例讲述了Python基于BeautifulSoup和requests实现的爬虫功能.分享给大家供大家参考,具体如下: 爬取的目标网页:http://www.qianlima.com/zb/area_305/ 这是一个招投标网站,我们使用python脚本爬取红框中的信息,包括链接网址.链接名称.时间等三项内容. 使用到的Python库:BeautifulSoup.requests 代码如下: # -*- coding:utf-8 -*- import requests from bs4 im

  • Python如何使用BeautifulSoup爬取网页信息

    这篇文章主要介绍了Python如何使用BeautifulSoup爬取网页信息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 简单爬取网页信息的思路一般是 1.查看网页源码 2.抓取网页信息 3.解析网页内容 4.储存到文件 现在使用BeautifulSoup解析库来爬取刺猬实习Python岗位薪资情况 一.查看网页源码 这部分是我们需要的内容,对应的源码为: 分析源码,可以得知: 1.岗位信息列表在<section class="widg

  • Python HTML解析器BeautifulSoup用法实例详解【爬虫解析器】

    本文实例讲述了Python HTML解析器BeautifulSoup用法.分享给大家供大家参考,具体如下: BeautifulSoup简介 我们知道,Python拥有出色的内置HTML解析器模块--HTMLParser,然而还有一个功能更为强大的HTML或XML解析工具--BeautifulSoup(美味的汤),它是一个第三方库.简单来说,BeautifulSoup最主要的功能是从网页抓取数据.本文我们来感受一下BeautifulSoup的优雅而强大的功能吧! BeautifulSoup安装 B

  • Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释

    一.Tag(标签)对象 1.Tag对象与XML或HTML原生文档中的tag相同. from bs4 import BeautifulSoup soup = BeautifulSoup('<b class="boldest">Extremely bold</b>','lxml') tag = soup.b type(tag) bs4.element.Tag 2.Tag的Name属性 每个tag都有自己的名字,通过.name来获取 tag.name 'b' tag.

  • python3 BeautifulSoup模块使用字典的方法抓取a标签内的数据示例

    本文实例讲述了python3 BeautifulSoup模块使用字典的方法抓取a标签内的数据.分享给大家供大家参考,具体如下: # -*- coding:utf-8 -*- #python 2.7 #XiaoDeng #http://tieba.baidu.com/p/2460150866 #标签操作 from bs4 import BeautifulSoup import urllib.request import re #如果是网址,可以用这个办法来读取网页 #html_doc = "htt

  • Python BeautifulSoup [解决方法] TypeError: list indices must be integers or slices, not str

    在python的Beautiful Soup 4 扩展库的使用过程中出现了 TypeError: list indices must be integers or slices, not str 这个错误,这里就分析一下为什么会报错以及如何解决. 这个错误的意思是'类型错误:list的索引必须是'integers'或者'slices'不能是'str' 我出现错误的代码: #引入库 from bs4 import BeautifulSoup #读取页面 soup = BeautifulSoup(o

  • python中bs4.BeautifulSoup的基本用法

    导入模块 from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc,"html.parser") 下面看下常见的用法 print(soup.a) # 拿到soup中的第一个a标签 print(soup.a.name) # 获取a标签的名称 print(soup.a.string) # 获取a标签的文本内容 print(soup.a.text) # 获取a标签的文本内容 print(soup.a["href"

  • 使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解

    下面就是使用Python爬虫库BeautifulSoup对文档树进行遍历并对标签进行操作的实例,都是最基础的内容 html_doc = """ <html><head><title>The Dormouse's story</title></head> <p class="title"><b>The Dormouse's story</b></p>

  • Python3爬虫学习之爬虫利器Beautiful Soup用法分析

    本文实例讲述了Python3爬虫学习之爬虫利器Beautiful Soup用法.分享给大家供大家参考,具体如下: 爬虫利器Beautiful Soup 前面一篇说到通过urllib.request模块可以将网页当作本地文件来读取,那么获得网页的html代码后,自然就是要将我们所需要的部分从杂乱的html代码中分离出来.既然要做数据的查找和提取,当然我们首先想到的应该是正则表达式的方式,而正则表达式书写的复杂我想大家都有体会,而且Python中的正则表达式和其他语言中的并没有太大区别,也就不赘述了

随机推荐