前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BeautifulSoup使用

BeautifulSoup使用

作者头像
听城
发布2018-08-30 11:09:41
9280
发布2018-08-30 11:09:41
举报
文章被收录于专栏:杂七杂八杂七杂八

安装

pip install beautifulsoup4

解析库

解析库

使用方法

优势

劣势

Python标准库

BeautifulSoup(mk, ‘html.parser’)

python的内置标准库、执行速度适中、文档容错能力强

Python2.7 or 3.2.2前的版本中文容错能力差

lxml的HTML解析器

BeautifulSoup(mk, ‘lxml’)

速度快、文档容错能力强

需要安装C语言库

bs4的XML解析器

BeautifulSoup(mk, ‘xml’)

速度快、唯一支持xml的解析器

需要安装C语言库

html5lib的解析器

BeautifulSoup(mk, ‘html5lib’)

最好的容错性、以浏览器的方式解析文档,生成html5格式文档

速度慢、不依赖外部库

基本使用

代码语言:javascript
复制
html = '''
<html><head><title>The Domouse'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 little sisters;and their names were
<a href="http://example.com/elsie"class="sister"id="link1"><!--Elsie--></a>
<a hred="http://example.com/lacle"class="sister"id="link2">Lacle</a>and
<a hred="http://example.com/tilie"class="sister"id="link3">Tillie</a>
and they lived at bottom of a well.</p>
<p class="story">...</p>
'''
 
from bs4 import BeautifulSoup
 
soup= BeautifulSoup(html,'lxml')
 
print(soup.prettify())#格式化代码,打印结果自动补全缺失的代码
 
print(soup.title.string)#文章标题

四大对象种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .

Tag

Tag 就是 HTML 中的标签,tag中最重要的属性: name和attributes。一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.Beautiful Soup提供了许多操作和遍历子节点的属性.注意: Beautiful Soup中字符串节点不支持这些属性,因为字符串没有子节点

tag的名字

操作文档树最简单的方法就是告诉它你想获取的tag的name.如果想获取 <head> 标签,只要用 soup.head :

代码语言:javascript
复制
soup.head
# <head><title>The Dormouse's story</title></head>

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

如果要使用嵌套选择,可以一直调用.,比如soup.body.b获取<body>标签中的第一个<b>标签。 通过点取属性的方式只能获得当前名字的第一个tag,如果想要得到所有的<a>标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到 Searching the tree 中描述的方法,比如: find_all()

tag的属性
代码语言:javascript
复制
print soup.p.attrs
#{'class': ['title'], 'name': 'dromouse'}
print soup.p['class']
#['title']
.contents 和 .children、.descendants

tag的 .contents 属性可以将tag的子节点以列表的方式输出,.children与contents的区别在于它将返回一个迭代器,.descendants 属性可以对所有tag的子孙节点进行递归循环

代码语言:javascript
复制
head_tag = soup.head
head_tag
# <head><title>The Dormouse's story</title></head>

head_tag.contents
[<title>The Dormouse's story</title>]

title_tag = head_tag.contents[0]
title_tag
# <title>The Dormouse's story</title>
title_tag.contents
# [u'The Dormouse's story']

与孩子相对的有父节点,祖先节点,兄弟节点等,可以参考文档https://beautifulsoup.readthedocs.io/zh_CN/latest/#id18

NavigableString

既然我们已经得到了标签的内容,那么问题来了,我们要想获取标签内部的文字怎么办呢?很简单,用 .string 即可,例如print soup.p.string #The Dormouse's story

BeautifulSoup

BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性来感受一下

代码语言:javascript
复制
print type(soup.name)
#<type 'unicode'>
print soup.name 
# [document]
print soup.attrs 
#{} 空字典

Comment

Comment 对象是一个特殊类型的 NavigableString 对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦。

代码语言:javascript
复制
print soup.a
print soup.a.string
print type(soup.a.string)
#<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --#></a>
# Elsie 
#<class 'bs4.element.Comment'>

a 标签里的内容实际上是注释,但是如果我们利用 .string 来输出它的内容,我们发现它已经把注释符号去掉了,所以这可能会给我们带来不必要的麻烦。

另外我们打印输出下它的类型,发现它是一个 Comment 类型,所以,我们在使用前最好做一下判断,判断代码如下

代码语言:javascript
复制
if type(soup.a.string)==bs4.element.Comment:
    print soup.a.string

搜索文档树

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

find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件

name 参数
  • 传字符串 最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容,下面的例子用于查找文档中所有的<b>标签
代码语言:javascript
复制
soup.find_all('b')
# [<b>The Dormouse's story</b>]
  • 传正则表达式 如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示<body>和<b>标签都应该被找到
代码语言:javascript
复制
import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b
  • 传列表 如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签soup.find_all(["a", "b"])
  • 传方法 如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数,如果这个方法返回True表示当前元素匹配并且被找到,如果不是则返回 False
代码语言:javascript
复制
下面方法校验了当前元素,如果包含 class 属性却不包含 id 属性,那么将返回 True:
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)
# [<p class="title"><b>The Dormouse's story</b></p>,
#  <p class="story">Once upon a time there were...</p>,
#  <p class="story">...</p>]
keyword 参数
代码语言:javascript
复制
soup.find_all(id='link2')
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
soup.find_all(href=re.compile("elsie"))
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]
soup.find_all("a", class_="sister")
# [<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>]
data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
data_soup.find_all(data-foo="value")
# SyntaxError: keyword can't be an expression
data_soup.find_all(attrs={"data-foo": "value"})
# [<div data-foo="value">foo!</div>]

select

我们在写 CSS 时,标签名不加任何修饰,类名前加点,id名前加 #,在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),select 方法返回的结果都是列表形式,可以遍历形式输出,然后用 get_text() 方法来获取它的内容。

代码语言:javascript
复制
print soup.select('a[class="sister"]')
#[<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 = BeautifulSoup(html, 'lxml')
print type(soup.select('title'))
print soup.select('title')[0].get_text()

for title in soup.select('title'):
    print title.get_text()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.08.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装
  • 解析库
  • 基本使用
  • 四大对象种类
    • Tag
      • tag的名字
      • tag的属性
      • .contents 和 .children、.descendants
    • NavigableString
      • BeautifulSoup
        • Comment
        • 搜索文档树
          • find_all( name , attrs , recursive , text , **kwargs )
            • name 参数
            • keyword 参数
          • select
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档