Python BeautifulSoup4的使用方法

1. 安装方法

这里只介绍windows平台安装BeautifulSoup包的方法,主要有两种:
方法1. 直接在cmd窗口输入

pip install beautifulsoup4

方法2. 下载BS4的源码,通过setup.py来安装。setup.py的安装是在对应文件路径下打开cmd窗口,然后输入指令

python setup.py install

2. 使用方法

具体可查看官方文档,这里做一些简要介绍。

2.1 浏览器解析器

lxml 解析器更加强大,速度更快,推荐安装和使用。

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

2.2 创建 Beautiful Soup 对象

先创建一个字符串,用于后面的文本处理

html = """
<html><head><title>The Dormouse'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 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>
"""

那么创建BeautifulSoup对象的方法如下

from bs4 import BeautifulSoup  # 首先必须先导入bs4库
soup = BeautifulSoup(html, 'lxml')  # 创建BeautifulSoup对象

也可以打开本地的HTML文件来创建对象,例如

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

其中demo.html是本地文件

2.3 四大对象种类

HTML文档被BeautifulSoup转化为一个树状结构,每个节点都是Python对象。这些对象可以归纳为4类:

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

(1) Tag
如果你了解html基础知识的话,就知道Tag是标签。

<title>The Dormous's story</title>
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

这里的title、a等就是Tag。那么BeautifulSoup是如何处理Tag的呢?

print(soup.title)
#<title>The Dormouse's story</title>
print soup.head
#<head><title>The Dormouse's story</title></head>
print soup.a
#<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
print soup.p
#<p class="title" name="dromouse"><b>The Dormouse's story</b></p>

Tag有两个重要的属性,name和attrs。

name

print(soup.name)
print(soup.head.name)
#[document]
#head

attrs

print(soup.p.attrs)
#{'class': ['title'], 'name': 'dromouse'}

主要返回结果是一个dic型数据,而且只获得第一个符合要求的Tag。
如果想单独获取某个属性,比如说class属性,可以这么写

print(soup.p['class'])
#['title']

也可以用get方法

print(soup.p.get('class'))
#['title']

(2) NavigableString
NavigableString即可遍历的字符串。Tag内的文本信息可通过.string获取,返回的结果就是NavigableString类型的数据。

print(soup.p.string)
#The Dormouse's story
print(type(soup.p.string))
#<class 'bs4.element.NavigableString'>

(3) BeautifulSoup
BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作一个特殊的 Tag。

print type(soup.name)
#<type 'unicode'>
print soup.name 
# [document]
print soup.attrs 
#{} 空字典

(4) Comment

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

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 来输出它的内容,我们发现它已经把注释符号去掉了。

2.4 搜索文档树

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

<name参数>
name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉。下面是name可以传入的参数类型。

  • 传字符串

    这个最简单,如要查找文档中所有的<a>的Tag

soup.find_all('a')
  • 传正则表达式

如果传入正则表达式为参数,BeautifulSoup会通过正则表达式的match()来匹配内容。

import re
for tag in soup.find_all(re.compile('^b')):
    print(tag.name)
  • 传列表

如果传入列表参数,BeautifulSoup会将与列表中任一元素匹配的内容返回。

soup.find_all(['a', 'b'])

上面代码运行后会将文档中所有<a>标签和<b>标签筛选出来。

  • 传True

True可以匹配任何值。

for tag in soup.find_all(True):
    print(tag.name)
  • 传方法

如果没有合适过滤器,还可定义一个方法。方法只接受一个元素参数,如果这个方法返回 True,则表示当前元素匹配并且被找到。

def class_noid(tag):
    return tag.has_attr('class') and not tag.has_attr('id')

for tag in soup.find_all(class_noid):
    print(tag)

<keyword参数>

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

soup.find_all(id='link2')
soup.find_all(href=re.compile('elsie'))
soup.find_all(href=re.compile('elsie'), id='link1')  # 可以设置多个关键字参数进行过滤

注意,如果想用class做关键字参数,需要加个下划线(因为class是python的关键词)

soup.find_all('a', class_='sister')

有些tag属性无法用于搜索,如下

soup1 = BeautifulSoup('<div data-foo="value">foo!</div>')
soup1.find_all(data-foo="value")

这个时候可以通过fiand_all()的attrs参数定义一个字典参数,来搜索包含特殊属性的tag

soup1.find_all(attrs={'data-foo': 'value'})

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

soup.find_all(text='Elsie')
soup.find_all(text=['Tillie', 'Elsie', 'Lacie'])
soup.find_all(text=re.compile('Dormouse'))

<limit参数>
limit参数是用于限制返回结果数目的参数,一般用于搜索文档大,返回结果多的情况。

soup.find_all('a', limit=2)

<recursive参数>
调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False。

html = '''
<html>
 <head>
  <title>
   The Dormouse's story
  </title>
 </head>
 '''
soup.html.find_all("title")
# [<title>The Dormouse's story</title>]

soup.html.find_all("title", recursive=False)
# []

注:以下(2)(3)(4)(5)(6)(7)方法参数用法与 find_all() 完全相同,原理均类似,在此不再赘述。

(2)find(name, attrs, recursive, text, **kwargs)
find()直接返回结果,而find_all()返回列表。其他无区别。

(3)find_parents() find_parent()
find_all() 和 find() 只搜索当前节点的所有子节点,孙子节点等。 find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通Tag的搜索方法相同,搜索文档搜索文档包含的内容。

(4)find_next_siblings() find_next_sibling()

这2个方法通过 .next_siblings 属性对当 tag 的所有后面解析的兄弟 tag 节点进行迭代,find_next_siblings() 方法返回所有符合条件的后面的兄弟节点,find_next_sibling() 只返回符合条件的后面的第一个tag节点。

(5)find_previous_siblings() find_previous_sibling()

这2个方法通过 .previous_siblings 属性对当前 tag 的前面解析的兄弟 tag 节点进行迭代, find_previous_siblings() 方法返回所有符合条件的前面的兄弟节点, find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点。

(6)find_all_next() find_next()

这2个方法通过 .next_elements 属性对当前 tag 的之后的 tag 和字符串进行迭代, find_all_next() 方法返回所有符合条件的节点,find_next() 方法返回第一个符合条件的节点。

(7)find_all_previous() 和 find_previous()

这2个方法通过 .previous_elements 属性对当前节点前面的 tag 和字符串进行迭代, find_all_previous() 方法返回所有符合条件的节点,find_previous()方法返回第一个符合条件的节点。

2.5 CSS选择器

写CSS时,Tag不加任何修饰,class前加点,id前加#。这里利用这个特性来筛选元素,用到的方法是soup.select(),返回list数据类型。

(1)利用Tag查找

print(soup.select('title'))
print(soup.select('p'))

(2)利用class查找

print(soup.select('.sister'))

(3)利用id查找

print(soup.select('#link1'))

(4)组合查找
组合查找时,注意tag、class和id之间用空格分开

print(soup.select('p #link1'))

(5)属性查找
查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。

print(soup.select('a[class="sister"]'))
print(soup.select('a[href="http://example.com/elsie"]'))

同样,属性仍然可以与上述查找方式组合,不在同一节点的空格隔开,同一节点的不加空格。

print(soup.select('p a[href="http://example.com/elsie"]'))

以上的 select 方法返回的结果都是列表形式,可以遍历形式输出,然后用 get_text() 方法来获取它的内容。

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())
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值