BeautifulSoup笔记
from bs4 import BeautifulSoup
html = '....'
soup = BeautifulSoup(html, 'lxml')
格式化输出
print soup.prettify()
Tag类型
输出html中的标签,它查找的是在所有内容中的第一个符合要求的标签
soup.head
soup.input
1. 属性
a) name
print soup.head.name
print soup.input.name
b) attrs
打印指定标签的所有属性,得到的类型是一个字典
print soup.input.attrs
# {'type': 'hidden', 'value': 'jining'}
访问某个属性的值,可以使用下面的几种方法
soup.input['type']
soup.input.get('type')
soup.input.attrs['type']
soup.input.attrs.get('type')
修改属性
soup.input['type']='temp'
删除属性
del soup.input['type']
c) contents
将子节点存储为列表
print soup.head.contents
#[<title>The Dormouse's story</title>]
用列表索引来获取它的某一个元素
print soup.head.contents[0]
d) children
将子节点存储为list列表生成器,用于for in循环遍历
for child in soup.body.children:
print child
e) descendants
递归遍历所有子孙节点
f) string
见NavigableString类型
g) strings
获取所有Tag的内容,使用for in 遍历读取
for string in soup.strings:
print(repr(string))
h) stripped_strings
去除了多个空格和空行的strings
i) parent
父节点
Tag的父节点是上一个节点
string的父节点是本节点
j) parents
递归所有父节点,使用for in 遍历读取
k) next_sibling previous_sibling
next_sibling 下一个兄弟节点
previous_sibling 上一个兄弟节点
如果没有兄弟节点,返回None
因为空白或换行也被视为一个节点,所以经常会获取到字符串或空白
l) next_siblings previous_siblings
全部兄弟节点
m) next_element previous_element
前后节点,视觉上的前后,不分层次
n) next_elements previous_elements
所有前后节点
2. 方法
a) find_all(name , attrs , recursive , text , **kwargs)
搜索当前tag的所有子孙节点
1) name
i. 传字符串
print soup.find_all('a')
ii. 传正则
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
iii. 传列表
soup.find_all(["a", "b"])
iv. 传True
for tag in soup.find_all(True):
print(tag.name)
v. 传方法
def has_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id')
soup.find_all(has_class_but_no_id)
2) attrs
如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性
soup.find_all(id='link2')
soup.find_all(href=re.compile("elsie"))
soup.find_all(href=re.compile("elsie"), id='link1')
class属性后面加下划线
soup.find_all("a", class_="sister")
特殊的属性,使用attrs参数
data_soup.find_all(attrs={"data-foo": "value"})
3) text
通过 text 参数可以搜搜文档中的字符串内容。与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表, True
如果通过这个搜索到节点,那么搜到的节点是内容,而不是标签
soup.find_all(text="Elsie")
# [u'Elsie']
soup.find_all(text=["Tillie", "Elsie", "Lacie"])
# [u'Elsie', u'Lacie', u'Tillie']
soup.find_all(text=re.compile("Dormouse"))
#[u"The Dormouse's story", u"The Dormouse's story"]
4) limit
限制返回结果的数量
soup.find_all("a", limit=2)
5) recursive
如果只搜索子节点,recursive=False
b) find( name , attrs , recursive , text , **kwargs )
它与 find_all() 方法唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果
c) find_parents() find_parent()
find_all() 和 find() 只搜索当前节点的所有子节点,孙子节点等. find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容
d) find_next_siblings() find_next_sibling()
这2个方法通过 .next_siblings 属性对当 tag 的所有后面解析的兄弟 tag 节点进行迭代, find_next_siblings() 方法返回所有符合条件的后面的兄弟节点,find_next_sibling() 只返回符合条件的后面的第一个tag节点
e) find_previous_siblings() find_previous_sibling()
这2个方法通过 .previous_siblings 属性对当前 tag 的前面解析的兄弟 tag 节点进行迭代, find_previous_siblings() 方法返回所有符合条件的前面的兄弟节点, find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点
f) find_all_next() find_next()
这2个方法通过 .next_elements 属性对当前 tag 的之后的 tag 和字符串进行迭代, find_all_next() 方法返回所有符合条件的节点, find_next() 方法返回第一个符合条件的节点
g) find_all_previous() 和 find_previous()
这2个方法通过 .previous_elements 属性对当前节点前面的 tag 和字符串进行迭代, find_all_previous() 方法返回所有符合条件的节点, find_previous()方法返回第一个符合条件的节点
h) select()
i. 标签名
print soup.select('title')
#[<title>The Dormouse's story</title>]
ii. 类名
print soup.select('.sister')
iii. id
print soup.select('#link1')
iv. 组合
print soup.select('p #link1')
v. 属性
print soup.select('a[class="sister"]')
print soup.select('a[href="http://example.com/elsie"]')
i) get_text()
获取内容,同string属性
NavigableString类型
输出标签的内容
print soup.title.string
如果一个标签里面没有标签了,那么 .string 就会返回标签里面的内容。如果标签里面只有唯一的一个标签了,那么 .string 也会返回最里面的内容
如果tag包含了多个子节点,tag就无法确定,string 方法应该调用哪个子节点的内容, .string 的输出结果是 None
BeautifulSoup类型
表示的是一个文档的全部内容,可以把它当作 Tag 对象
print type(soup)
Comment类型
当标签的内容被注释了的话,那么就是这个类型
<p><!-- 这里是注释内容 --></p>
print type(soup.p.string)