Python 爬虫库 – 使用 Beautiful Soup4.4.0
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这个网页来讲解如下图的例子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 属性,可以获取标签的名称 一个标签可以包含很多属性,比如 id、class 等,操作标签属性的方法是一样的作为字典。 例如,网页包含缩略图区域标签 article 获取它 class 的值属性 也可以直接从.attrs获取所有属性 ps。由于 class 是一个多值属性,因此它的值是一个数组。 通过string方法检索标签中的字符串 一个标签可以包含多个字符串或其他标签。这些是该标签的子节点。 Beautiful Soup 提供了很多用于遍历子节点的操作和属性。 对应的标签可以从Tag的名称获得。多次调用该方法即可获取子节点中对应的标签。 如下图: 我们希望打印结果中文章标签li : 你也可以省略一些节点中间,结果也一致。 只能通过属性.获取第一个标签。如果你想获得所有li标签,你可以使用find_all( )。 方法 获取所有li 标签的列表。 标签的.contents属性可以以列表形式显示该标签的子节点: print contents可以看到列表不仅包含li 标签内容还包含通过标签 .children 生成器换行符 '\n' ,该生成器可以在标签 的子节点上运行你可以看到children 的类型为 .contents 和 .children 属性仅包含标签的直接子节点。要遍历子节点的子节点,可以通过 .descendants 通过.parent属性获取元素的父节点。文章的父节点是body。 或通过属性.parents迭代所有父节点。属性 .next_sibling 和 .previous_sibling 用于插入姐妹节点,其使用方式与其他节点类似。 对树形结构文档的具体搜索是爬虫抓取过程中最常用的操作。 find_all(name , attrs , recursive , string , * kwargs)* 查找所有包含 的名称名字 \n 如果指定参数的名称不是内置参数名称(名称、属性、递归、字符串),则该参数将为作为标签的属性进行搜索。如果不指定标签,则默认搜索所有标签。 例如,搜索所有标签 \n,其值为footer 标签参数? thumb 需要注意的是,class是Python保留关键字,所以作为参数时加下划线,即“class_” ”。 指定名称的属性参数值可以包含:String 、正则表达式、List 、 对/错也 指定的属性是否存在。 搜索所有带有属性target属性的标签 搜索所有不带有target属性的标签(仔细看会发现搜索结果还是 target 标签是没有target标签的子标签,需要注意这一点。) 可以指定多个参数作为过滤条件。例如页面缩略图部分的标签如下: Search src 属性包含字符串reeoo,class是标签懒: 搜索结果均为缩略图img 标签。 有些属性不能作为参数使用,例如data-*属性。上例中,data-original不能作为参数使用,执行SyntaxError: keywords can not be an expression时报错。 定义一个字典参数来查找对应属性的标签,可以在一定程度上解决上述某些属性不能作为参数的问题。 例如,搜索包含属性 data-original 的标签。搜索包含属性 data-original 包含属性 reeoo.com 字符串标签 搜索标签 data-original其属性为指定值 与 name 参数类似,其目标是文档中的字符串内容。 搜索包含字符串Reeoo的标签: 打印搜索结果,你会看到包含3个元素,这就是对应标签的内容。详情请参见下图 find_all() 返回整个文档的搜索结果。如果文档内容很大,搜索过程将花费很长时间。添加 如果结果达到值limit,则停止搜索并返回结果。 搜索class到thumb到div标签,仅搜索for 3 打印结果是一个有3个元素的列表,实际上满足结果文档中有超过3个标签。 find_all()检索当前标签的所有子节点。如果只想搜索标签的直接子级,可以使用参数 recursive=Fal se。 find(name, attrs, recursive, string, * kwargs)* find()方法和find_all() 使用方法参数 基本相同,只不过find()的搜索方法只返回第一个符合要求的结果,相当于find_all()方法,设置了极限 为 1。 搜索结果是一样的,唯一的区别是find_all()返回一个数组,而find()返回一个元素。 如果没有找到符合条件的标签,则返回 find() None 和 find_all()返回一个空列表。对象 Tag 或 BeautifulSoup 通过方法 select() 传递。使用 label 的 CSS 选择器语法。 语义与CSS类似。在标签 li 标签 Z 下搜索文章 o 通过类名搜索,两行代码结果一致,搜索对于 class 对于标签 thumb 按 id,搜索 id 是赞助商的标签 通过或未通过 存在要查找的属性。搜索具有属性 id 的 li 标签。根据属性值搜索 id。 是赞助的li标签 其他搜索方法有: find_parents() 和 find_parent() find_next_siblings()和find_next_sibling() find_previous_siblings()和find_previous_sibling( ) ... 参数和的作用find_all( )、 find() 没有太大区别,这里就不提使用方法了。这两种方式基本可以满足大部分查询需求。 还有修改文档树的方法。对于爬虫来说,大部分工作都是检索页面信息,很少需要对页面的源代码进行更改。因此,这部分内容这里不再赘述。 具体详情请直接参考图书馆官方文档美丽汤print tag.name
# title
属性
...
...
tag = soup.article
c = tag['class']
print c
# [u'box']
tag = soup.article
attrs = tag.attrs
print attrs
# {u'class': [u'box']}
标签中的字符串
tag = soup.title
s = tag.string
print s
# Reeoo - web design inspiration and website gallery
文档树的遍历
子节点
2.jpg
tag = soup.article.div.ul.li
print tag
tag = soup.article.li
ls = soup.article.div.ul.find_all('li')
tag = soup.article.div.ul
contents = tag.contents
父节点
tag = soup.article
print tag.parent.name
# body
tag = soup.article
for p in tag.parents:
print p.name
同级节点
搜索文档树
find_all()
name 参数
\n\n...soup.find_all('title')
# []
soup.find_all('footer')
# [
]
关键字参数
\n\n...soup.find_all(id='footer')
# [
]
soup.find_all('div', class_='thumb')
True/False
soup.find_all(target=True)
soup.find_all(target=False)
...
...
soup.find_all(src=re.compile("reeoo.com"), class_='lazy')
attrs 参数
print soup.find_all(attrs={'data-original': True})
soup.find_all(attrs={'data-original': re.compile("reeoo.com")})
soup.find_all(attrs={'data-original': 'http://media.reeoo.com/Bersi Serlini Franciacorta.png!page'})
字符串参数
soup.find_all(string=re.compile("Reeoo"))
3。 jpg
4.jpg
5.jpg
limit 参数
soup.find_all('div', class_='thumb', limit=3)
递归参数
find()
soup.find_all('div', class_='thumb', limit=1)
soup.find('div', class_='thumb')
CSS Selector
print soup.select('article ul li')
soup.select('.thumb')
soup.select('[class~=thumb]')
soup.select('#sponsor')
soup.select('li[id="sponsor"]')
其他
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。