Code前端首页关于Code前端联系我们

Python 爬虫库 – 使用 Beautiful Soup4.4.0

terry 2年前 (2023-09-25) 阅读数 45 #后端开发

Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库。简单来说,它可以解析树形结构的HTML标签文件。然后轻松获取指定标签对应的属性。

比如上一篇文章中使用爬虫爬取漫画图片,得到的信息纯粹是使用正则表达式进行处理。这种方法比较复杂,代码的可读性也较低。通过库Beautiful Soup我们可以使用指定的class或id值作为参数,直接获取对应标签的相关数据。这种处理方法简单明了。

美丽汤最新版本是4.4.0。 《美丽汤 3》目前已停止维护。

美丽汤4适用于Python2.7和Python3.0。本文示例中使用的Python版本是2.7。

博主使用的是Mac系统,直接通过命令安装库:

sudo easy_install beautifulsoup4

安装完成后,尝试运行提供的库:

from bs4 import BeautifulSoup

如果没有报错,则表示库已安装通常情况下。

开始

本文使用reeoo.com这个网页来讲解如下图的例子Python 爬虫库 – Beautiful Soup4.4.0 的使用1.jpg

BeautifulSoup对象的初始化

在中传递一个文档美丽Soup 的构造方法可以产生一个文档对象。如下代码所示,通过请求URL获取文档:

#coding:utf-8

from bs4 import BeautifulSoup
import urllib2

url = 'http://reeoo.com'
request = urllib2.Request(url)
response = urllib2.urlopen(request, timeout=20)

content = response.read()
soup = BeautifulSoup(content, 'html.parser')

request 该请求不会进行任何异常处理,因此暂时忽略。 BeautifulSoup 构造函数的第二个参数是文档解析器。如果不传递此参数,BeautifulSoup将选择最合适的解析器来解析文档,但会出现警告。

也可以通过文件句柄初始化。可以先将HTML源代码保存到本地同级文件夹reo.html,然后以文件名作为参数:

soup = BeautifulSoup(open('reo.html'))

可以打印soup,输出内容与 HTML 文本相同。现在它是一个复杂的树结构,每个节点都是一个Python对象。

Ps。下面示例代码中使用的soup都是汤。

Tag

Tag 对象与 HTML 原生文档中的 tag 相同,可以直接从对应名称中获取

tag = soup.title
print tag

打印结果:

Name

Tag 对象的 name 属性,可以获取标签的名称

print tag.name
# title

属性

一个标签可以包含很多属性,比如 id、class 等,操作标签属性的方法是一样的作为字典。

例如,网页包含缩略图区域标签 article

...



...

获取它 class 的值属性

tag = soup.article
c = tag['class']

print c        
# [u'box']

也可以直接从.attrs获取所有属性

tag = soup.article
attrs = tag.attrs

print attrs
# {u'class': [u'box']}

ps。由于 class 是一个多值属性,因此它的值是一个数组。

标签中的字符串

通过string方法检索标签中的字符串

tag = soup.title
s = tag.string

print s
# Reeoo - web design inspiration and website gallery

文档树的遍历

一个标签可以包含多个字符串或其他标签。这些是该标签的子节点。 Beautiful Soup 提供了很多用于遍历子节点的操作和属性。

子节点

对应的标签可以从Tag名称获得。多次调用该方法即可获取子节点中对应的标签。

如下图:Python 爬虫库 – Beautiful Soup4.4.0 的使用2.jpg

我们希望打印结果中文章标签li

tag = soup.article.div.ul.li
print tag


你也可以省略一些节点中间,结果也一致。

tag = soup.article.li

只能通过属性.获取第一个标签。如果你想获得所有li标签,你可以使用find_all( )。 方法

ls = soup.article.div.ul.find_all('li')

获取所有li 标签的列表。

标签的.contents属性可以以列表形式显示该标签的子节点:

tag = soup.article.div.ul
contents = tag.contents

print contents可以看到列表不仅包含li 标签内容还包含通过标签 .children 生成器换行符 '\n'

,该生成器可以在标签 的子节点上运行你可以看到children 的类型为

.contents.children 属性仅包含标签的直接子节点。要遍历子节点的子节点,可以通过 .descendants

。属性和方法与前两者类似,这里不再列出。

父节点

通过.parent属性获取元素的父节点。文章的父节点是body。

tag = soup.article
print tag.parent.name
# body

或通过属性.parents迭代所有父节点。属性

tag = soup.article
for p in tag.parents:
    print p.name

同级节点

.next_sibling.previous_sibling 用于插入姐妹节点,其使用方式与其他节点类似。

搜索文档树

对树形结构文档的具体搜索是爬虫抓取过程中最常用的操作。

find_all()

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

name 参数

查找所有包含 的名称名字

的标签

soup.find_all('title')
# []

soup.find_all('footer')
# [
\n\n...

\n

]
关键字参数

如果指定参数的名称不是内置参数名称(名称、属性、递归、字符串),则该参数将为作为标签的属性进行搜索。如果不指定标签,则默认搜索所有标签。

例如,搜索所有标签

soup.find_all(id='footer')
# [
\n\n...

\n,其值为footer

]

标签参数? thumb

标记

soup.find_all('div', class_='thumb')

需要注意的是,class是Python保留关键字,所以作为参数时加下划线,即“class_” ”。

指定名称的属性参数值可以包含:String 正则表达式List 、 对/错也

True/False

指定的属性是否存在。

搜索所有带有属性target属性的标签

soup.find_all(target=True)

搜索所有不带有target属性的标签(仔细看会发现搜索结果还是 target 标签是没有target标签的子标签,需要注意这一点。)

soup.find_all(target=False)

可以指定多个参数作为过滤条件。例如页面缩略图部分的标签如下:

...
  • ![AIM Creative Studios](http://upload-images.jianshu.io/upload_images/1346917-f6281ffe1a8f0b18.gif?imageMogr2/auto- orient/ strip ) AIM Creative Studios


...

Search src 属性包含字符串reeooclass是标签

soup.find_all(src=re.compile("reeoo.com"), class_='lazy')

搜索结果均为缩略图img 标签。

有些属性不能作为参数使用,例如data-*属性。上例中,data-original不能作为参数使用,执行SyntaxError: keywords can not be an expression时报错。

attrs 参数

定义一个字典参数来查找对应属性的标签,可以在一定程度上解决上述某些属性不能作为参数的问题。

例如,搜索包含属性 data-original

print soup.find_all(attrs={'data-original': True})

的标签。搜索包含属性 data-original 包含属性 reeoo.com 字符串标签

soup.find_all(attrs={'data-original': re.compile("reeoo.com")})

搜索标签 data-original其属性为指定值

soup.find_all(attrs={'data-original': 'http://media.reeoo.com/Bersi Serlini Franciacorta.png!page'})
字符串参数

name 参数类似,其目标是文档中的字符串内容。

搜索包含字符串Reeoo的标签:

soup.find_all(string=re.compile("Reeoo"))

打印搜索结果,你会看到包含3个元素,这就是对应标签的内容。详情请参见下图Python 爬虫库 – Beautiful Soup4.4.0 的使用3。 jpgPython 爬虫库 – Beautiful Soup4.4.0 的使用4.jpgPython 爬虫库 – Beautiful Soup4.4.0 的使用5.jpg

limit 参数

find_all() 返回整个文档的搜索结果。如果文档内容很大,搜索过程将花费很长时间。添加 如果结果达到值limit,则停止搜索并返回结果。

搜索classthumbdiv标签,仅搜索for 3

soup.find_all('div', class_='thumb', limit=3)

打印结果是一个有3个元素的列表,实际上满足结果文档中有超过3个标签。

递归参数

find_all()检索当前标签的所有子节点。如果只想搜索标签的直接子级,可以使用参数 recursive=Fal se

find()

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

find()方法和find_all() 使用方法参数 基本相同,只不过find()的搜索方法只返回第一个符合要求的结果,相当于find_all()方法,设置了极限 为 1。

soup.find_all('div', class_='thumb', limit=1)
soup.find('div', class_='thumb')

搜索结果是一样的,唯一的区别是find_all()返回一个数组,而find()返回一个元素。

如果没有找到符合条件的标签,则返回 find() Nonefind_all()返回一个空列表。对象

CSS Selector

TagBeautifulSoup 通过方法 select() 传递。使用 label 的 CSS 选择器语法。

语义与CSS类似。在标签 li 标签

print soup.select('article ul li')

Z 下搜索文章 o 通过类名搜索,两行代码结果一致,搜索对于 class 对于标签 thumb

soup.select('.thumb')
soup.select('[class~=thumb]')

按 id,搜索 id 是赞助商的标签

soup.select('#sponsor')

通过或未通过 存在要查找的属性。搜索具有属性 idli 标签。根据属性值搜索 id。 是赞助li标签

soup.select('li[id="sponsor"]')

其他

其他搜索方法有:

find_parents()find_parent()

find_next_siblings()find_next_sibling()

find_previous_siblings()find_previous_sibling( )

...

参数和的作用find_all( ) find() 没有太大区别,这里就不提使用方法了。这两种方式基本可以满足大部分查询需求。

还有修改文档树的方法。对于爬虫来说,大部分工作都是检索页面信息,很少需要对页面的源代码进行更改。因此,这部分内容这里不再赘述。

具体详情请直接参考图书馆官方文档美丽汤

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门