BeautifulSoup的用法

此文档是根据BeautifulSoup4.4.0官方文档总结而来

BeautifulSoup中的对象

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

Tag(标签)

# tag就是Tag对象,对象的name是html标签名,也就是p
soup = BeautifulSoup('<p id="test_id" class="test-class">hello world!</p>','lxml')
tag = soup.p
# html里p的attributes也就变成了tag的attributes
tag['class']  ==>  ['test-class']  #class可能是多个,所以是个数组
tag['id']  ==>  'test_id' #id只会是一个

NavigableString(标签里的内容)

上面说的p标签转成tag对象,那p标签里的内容则会转成字符串对象

# str就是NavigableString对象,
str = tag.string
# tag中字符串不能被编辑,但是可以替换成其他字符串
str.replace_with('yes')
print(tag)  ==>  <p class="test-class" id="test_id">yes</p>

BeautifulSoup(文档对象)

BeautifulSoup对象和tag类似,但是它没有name和attribute属性

Comment(注释)

一个html页面,里面除了标签,还有注释部分,这就需要Comment对象

#Comment对象也是通过Tag对象来获取,得到的是注释里面的内容
soup = BeautifulSoup('<p><!-- 注释部分 --></p>','lxml')
comment = soup.p.string   ==>  注释部分

遍历文档树

示例html

html_doc = """
    <html>
        <head>
            <title>The Dormouse story</title>
        </head>
        <body>
            <p class="title">
                <b>The Dormouse 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>
        </body>
    </html>
    """

子节点

soup = BeautifulSoup(html_doc,'lxml')
# 获取第一个a标签
soup.a
# 获取所有的a标签
soup.find_all('a')
# tag的.contents属性可以将tag的子节点以列表方式输出
soup.head.contents  ==>  ['\n', <title>The Dormouse story</title>, '\n']
soup.head.contents[1].contents  ==>  ["The Dormouse story"]
# .children对tag直接子节点循环
for child in head.children:
    print (child)   ==>  <title>The Dormouse story</title>
# .descendants对tag所有子节点递归循环
for child in head.descendants:
    print (child)   ==>  <title>The Dormouse story</title> 和 The Dormouse story
# 当tag中有多个字符串时,使用strings,去除空格用stripped_strings
for string in soup.stripped_strings:
    print (repr(string))

父节点

# .parent获取元素父节点
soup.title.parent
# .parent递归查找所有父节点
soup.a.parents
# .next_sibling下一个兄弟节点,.previous_sibling上一个兄弟节点
# .next_siblings和.previous_siblings递归查找兄弟节点

搜索文档树

方法参数

# 字符串。查找所有b标签
soup.find_all('b')
# 正则表达式。查找所有以b开头的标签
import re
soup.find_all("^b")
# 列表。查找所有a标签和b标签
soup.find_all(['a','b'])
# True。查找所有
soup.find_all(True)
# 方法。可以将方法作为参数,方法返回True或者False,find_all()据此查找
# 查找所有包含class属性但不包含id属性的元素
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)

find_all()

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

# name参数。根据tag的name查找
soup.find_all('title')
# attrs参数。根据class查找,但是class是python的保留字,需要用class_
soup.find_all('a',class_='sister')
soup.find_all('a',attrs={'class':'sister'})
# recursive参数。recursive=False查找直接子节点
soup.head.find_all('title',recursive=False)
# string参数。与文档中字符串内容匹配。
soup.find_all('a',string='Elsie')
# kwargs参数。自定义参数
soup.find_all(id='link2')
soup.find_all(href=re.compile("elsie"))
soup.find_all(id=True)
# limit参数。
soup.find_all('a',limit=2)

find_all()是最常用的方法之一,因此可以简写,例如

#这两个等价,写法和上面的Tag一样
soup.find_all('a')  ==>  soup('a')

find()

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

find()方法只返回一个结果

#这两个等价
soup.find_all('a',limit=1)  ==>  soup.find('a')

其他搜索

find_parents() 和 find_parent() 向上查找

find_next_siblings() 和 find_next_sibling() 向后查找

find_previous_siblings() 和 find_previous_sibling() 向前查找

CSS选择器

# .select()可以使用css语法查找Tag
soup.select('title')
soup.select('html head title')
soup.select('html>head>title')
soup.select('.sister')
soup.select('#link1')
soup.select_one('.sister')

输出

格式化输出

# prettify()将文档格式化输出
print(soup.prettify())

压缩输出

# unicode()和str()可以将文档压缩输出
str(soup)  ==>  返回UTF-8编码的字符串
unicode(soup)  ==>  返回Unicode编码字符串

输出文本内容

# get_text()输出tag包括子孙tag中的内容(Unicode字符串)
soup.get_text()
# 指定分隔符
soup.get_text('|')
# 去除前后空白
soup.get_text('|',strip=True)
# 获得文本列表
soup.stripped_strings

编码

任何HTML或XML文档都有自己的编码方式,比如ASCII 或 UTF-8,但是使用Beautiful Soup解析后,文档都被转换成了Unicode

# .original_encoding 显示编码结果
soup.original_encoding
# from_encoding 指定编码方式
soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
# exclude_encodings 不使用此编码方式
soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])

输出编码

通过Beautiful Soup输出文档时,不管输入文档是什么编码方式,输出编码均为UTF-8编码

# 使用prettify()修改输出编码
print(soup.prettify("latin-1"))
# 调用encode()方法指定编码
soup.p.encode("utf-8")
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355