Beautiful Soup学习笔记

开始

首先必须要导入 bs4 库

from bs4 import BeautifulSoup

我自己常用的两种解析器

soup = BeautifulSoup(markup, "html.parser")
soup = BeautifulSoup(markup, "lxml")

如果要使用lxml必须先安装

pip install lxml

四大对象种类

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

Tag

Tag就是HTML中的一个个标签, 例如

The Dormouse's story
Elsie

验证一下对象类型

print(type(soup.a))
#

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

name

例如一个b标签, 那么它的name就是b, 一个p标签的name就是p

soup = BeautifulSoup('Extremely bold', 'lxml')
tag = soup.b
print(tag.name)
#b

attrs

attrs是一个字典类型的, 对应的是属性-值, 如print soup.p.attrs,输出的就是{'class': ['title'], 'name': 'dromouse'}, 当然你也可以得到具体的值, 如print(soup.p.attrs['class']),输出的就是[title]是一个列表的类型,因为一个属性可能对应多个值,当然你也可以通过get方法得到属性的, 如:print(soup.p.get('class')). 还可以直接使用print(soup.p['class'])

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

get

get方法用于得到标签下的属性值, 注意这是一个重要的方法, 在许多场合都能用到, 比如你要得到标签下的图像url, 那么就可以用soup.img.get('src'), 具体解析如下:

print soup.p.get("src")   #得到第一个p标签下的src属性

单独获取某个属性

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

也可以像下面这样

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

或者下面那样

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

find_all()

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

find_all() 方法搜索当前tag的所有tag子节点, 并判断是否符合过滤器的条件
注意:如果一个指定名字的参数不是搜索内置的参数名, 搜索时会把该参数当作指定名字tag的属性来搜索, 如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性
find_all() 的返回值是一个Tag组成的列表, 方法调用非常灵活, 所有的参数都是可选的, 这里有几个例子:

soup.find_all("title")
# [The Dormouse's story]

soup.find_all("p", "title")
# [

The Dormouse's story

] soup.find_all("a") # [Elsie, # Lacie, # Tillie] soup.find_all(id="link2") # [Lacie] import re soup.find(text=re.compile("sisters")) # u'Once upon a time there were three little sisters; and their names were\n'

name 参数

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

soup.find_all("title")
# [The Dormouse's story]

传字符串

soup.find_all('b')
# [The Dormouse's story]
print soup.find_all('a')
#[...]

传正则表达式

如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示和标签都应该被找到:
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b

传列表

如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有标签和标签:
soup.find_all(["a", "b"])

attrs参数

find_all()中第二个参数是标签的class属性值

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

等效于

soup.find_all("p", "sister") # p指定了tag的name, sister指定了所有tag的class属性如果是'sister'就会被返回

keyword参数

如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数, Beautiful Soup会搜索每个tag的”id”属性

soup.find_all(id='link2')
# [Lacie]
soup.find_all(href=re.compile("elsie"))
# [Elsie]

多个指定名字参数同时过滤tag的多个属性

soup.find_all(href=re.compile("elsie"), id='link1')
# [three]

定义一个字典来搜索包含特殊属性的tag

soup.find_all(attrs={"data-foo": "value"})
# [
foo!
]

text参数

soup.find_all(text="Elsie")
# 'Elsie'
soup.find_all(text=["Tillie", "Elsie"])
['Elsie', 'Tillie']
soup.find_all(text=re.compile("Dormouse"))
['The Dormouse's story]

find()方法

find( name , attrs , recursive , text , **kwargs )
它与 find_all() 方法唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果

get_text()

如果只想得到tag中包含的文本内容,那么可以使用 get_text() 方法, 这个方法获取到tag中包含的所有文版内容包括子孙tag中的内容, 并将结果作为Unicode字符串返回:

markup = '\nI linked to example.com\n'
soup = BeautifulSoup(markup)

soup.get_text()
u'\nI linked to example.com\n'
soup.i.get_text()
u'example.com'

可以通过参数指定tag的文本内容的分隔符:

# soup.get_text("|")
u'\nI linked to |example.com|\n'

还可以去除获得文本内容的前后空白:

# soup.get_text("|", strip=True)
u'I linked to|example.com'

或者使用 .stripped_strings 生成器,获得文本列表后手动处理列表:

[text for text in soup.stripped_strings]
# [u'I linked to', u'example.com']

css选择器

我们在写 CSS 时,标签名不加任何修饰,类名前加点,id名前加#,在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list

通过标签名查找

print soup.select('title') 
#[The Dormouse's story]
print soup.select('a')
#[, Lacie, Tillie]

通过类名查找

print soup.select('.sister')
#[, Lacie, Tillie]

通过id名查找

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

组合查找

学过css的都知道css选择器,如p #link1是查找p标签下的id属性为link1的标签

print soup.select('p #link1')    #查找p标签中内容为id属性为link1的标签
#[]
print soup.select("head > title")   #直接查找子标签
#[The Dormouse's story]

属性查找

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

print soup.select('a[class="sister"]')
#[, Lacie, Tillie]
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()

你可能感兴趣的:(Beautiful Soup学习笔记)