爬虫基础:BeautifulSoup库

BeautifulSoup是灵活又方便的网页解析库,处理高效,支持多种解析器。虽然正则表达式比较强大,但是能用“美味的汤”能更加方便实现网页信息的提取就优先使用吧。
官方文档:http://beautifulsoup.readthedocs.io/zh_CN/latest/

安装:

pip3 install beautifulsoup4

解析器选择

解析器 使用方法 优势 劣势
Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库,执行速度适中,文档容错能力强 Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器 BeautifulSoup(markup, "lxml") 速度快 文档容错能力强 需要安装C语言库
lxml XML 解析器 BeautifulSoup(markup, ["lxml", "xml"]) 速度快 唯一支持XML的解析器 需要安装C语言库
html5lib BeautifulSoup(markup, "html5lib") 最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档 速度慢 不依赖外部扩展

建议

  • 推荐使用lxml解析库,必要时使用html.parser
  • 标签使用筛选功能弱但是速度快
  • 建议使用find(),find_all()查询匹配单个结果或者多个结果
  • 如果对CSS选择器熟悉建议使用select()
  • 记住常用的获取属性和文本值的方法

重点部分

bs4对象种类

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

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# name
tag.name
# attributes
tag.attrs
tag.attrs['class']
tags['class']

搜索文档树

在学习find_all()之前需要了解过滤器。

过滤器

过滤器贯穿整个搜索的API.过滤器可以被用在tag的name中,节点的属性中,字符串中或他们的混合中,如下:
字符串:传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容

# 寻找所有<b>标签
soup.find_all('b')

正则表达式:Beautiful Soup会通过正则表达式的 match() 来匹配内容

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

列表:将与列表中任一元素匹配的内容返回

# <a>或<b>
soup.find_all(["a", "b"])

True: 所有标签
自定义方法:太高级,目前搞不定

# 过滤出前后都有文字的标签
def surrounded_by_strings(tag):
    return (isinstance(tag.next_element, NavigableString)
            and isinstance(tag.previous_element, NavigableString))
# 包含 class 属性却不包含 id 属性
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')
find_all():

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

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

name参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉

soup.find_all('body')

: 搜索 name 参数的值可以使任一类型的过滤器 ,字符串,正则表达式,列表,方法或是 True .

keyword参数: 如果一个指定名字的参数不是搜索<u>内置的参数名</u>,搜索时会把该参数当作指定名字tag的属性来搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索

for tag in soup.find_all(id=re.compile("^note-\d+")):
    print(tag.name)

:搜索指定名字的属性时可以使用的参数值包括字符串,正则表达式,列表, True.对于CSS样式,class因为和内部冲突,所以需要改为class_

string参数:通过 string 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, string 参数接受 字符串 , 正则表达式 , 列表, True .

print(soup.find_all(string="诗"))

recursive参数,默认搜索当前节点的所有子孙节点,如果只需要搜索直接节点,则recursive=False

PS: 由于find_all太常用,所以BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all() 方法

soup.title.find_all(string=True)
soup.title(string=True)

find_all还有其他类似方法,详见官方文档,不多说。CSS选择器不太熟悉,所以不去涉及select()方法。
获取文本的方法很简单,get_text()

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

推荐阅读更多精彩内容