python BeautifulSoup的常用语法
BeautifulSoup创建的soup对象可以将其格式化输出: print 文件名.prettify()
将html转换为四大对象种类:Tag、NavigableString、BeatuifulSoup、 Comment。
都用soup.html来作为样例文件
1.Tag(html里一个一个的标签)
Print sou.title | 输出title标签的内容 |
Tag的name属性:
Print soup.head.name | 就是head |
Print soup.name | bs的文件name就是 [document] |
Tag的 attrs属性:
Print soup.p.attrs | 打印所有p标签的属性,类型是一个 dic。 |
print soup.p[‘title’] | 打印p标签的是class名字的结果, |
Del soup.p[‘title’] | 删除p标签中title名字的属性。 |
2.NavigableString(标签内部的内容)
输出所有的字符串》》
NavigableString的用法:
Print soup.p.string | 打印p标签的内容 |
3.BeautifulSoup(一个特殊的Tag)
它就是文档全部的内容,大部分时候可以当做一个Tag。
试着获取它的类型和属性
Print type(soup.name) | 结果:#<type ‘unicode’> |
Print soup.name | #[document] |
Print soup.attrs | #{}(空的dic) |
4.Commment(特殊的NavigableString)
就是输出的内容不包括注释符号,但有时候会出现麻烦。
如:
Print soup.a | <a class=”sister” href=”http://asd.com” id=”link”><!–Elsie–></a> |
Print soup.a.string | Elsie |
Print type(soup.p.string) | <class “bs4.element.Comment”> |
2:遍历文档树
(1)直接的子节点:
.content:(tag的.content属性可以将tag的子节点以列表的形式输出)
Print soup.head.contents | 输出表列表,所以也能使用列表索引来获取他的一个元素,如:soup.head.contents[0] |
.children
获取所有子节点但不是一个list,可以通过遍历来获得所有子节点
for t in soup.body.children:
Print t |
输出了body的所有子节点 |
(2)所有子孙节点:
.descendants
.contents和.children 属性仅包含tag的直接子节点。.descendants 属性可以对所有tag的子孙节点进行递归循环,和.children 类似,我们要遍历获取其中的所有内容。
for t in soup.decendants:
Print t |
所有的节点都被打印书来了,先是最外层的html标签,然后是从head的标签一个个剥离。 |
(3)节点的内容:
.string
如果一个标签里面没有标签了,那么 .string 就会返回标签里面的内容。如果标签里面只有唯一的一个标签了,那么 .string 也会返回最里面的内容
Print soup.head.string | |
Print soup.title.string | |
Print soup.html.sreing | 如果有多个tagname就无法确定调用哪个节点的内容就会输出#None |
(4)多个内容:
.sreings
获取多个节点的内容,不过要遍历才能输出
for string in soup.strings:
Print string |
一个一个全部输出 |
.stripped_strings
和.strings类似,不过能够出去多余的空白内容,如换行、空格。也是要遍历输出
(5)父节点:
.parent
P=soup.p
Print p.parent.name |
#body |
(6)全部的父节点
.parrents
递归输出目标的全部父节点
S=soup.head.title.string
For parent in s.parents: Print parent.name |
Title
Head Html [document] |
(7)兄弟节点
.next_sibling .previous_sibling
兄弟节点就是和本节处在统一级的节点,.next_sibling获取下一个兄弟节点,.previous_sibling 获取上一个,如果没有,返回 #None
(8)全部的兄弟节点
.next_siblings .previous_siblings
可以迭代输出全部的兄弟节点
(9) 前后节点
.next_element .previous_element
这个和 .next_sibling .previous_sibling不同,这个对象是全部的节点,不分层次,不限于兄弟节点
(10)所有前后节点
.next_elements .previous_elements
3.搜索文档树:
(1)find_all(name,attrs,recusive,text,**kwargs)
find_all搜索当前所有tag节点,然后判断
- name参数
A。传字符串 BS会查找与字符串完整匹配的内容
soup.find_all(‘b’) | #[<b>The Dormouse’s story</b>] | 查找了b标签的内容 |
B。传正则表达式
Bs会通过正则表达式的match()来匹配内容
Import re
for tag in soup.find_all(re.compile(“^b”)): Print(tag.name) |
# b
#body |
查找了所有以b开头的标签 |
C。传列表
bs会将匹配列表中任意元素的内容返回
Soup.find_all([“a”,”b”]) | 会输出所有<a>,<b>标签 |
D。传True
True会匹配任何值
For tag in soup.find_all(True):
Print (tag,name) |
#html
#head #title 等等。 |
会输出所有tag但不会返回字符串 |
E。传方法
可以接受一个方法,如果返回true,则当前元素匹配被找到
Def has_class_but_no_id(tag):
Return tag.has_attr(‘class’) and not tag.has_attr(‘id’) |
校验了当前元素包含class属性但不包含id属性 |
Soup.find_all(has_class_but_no_id) | 就返回了所有<p> 标签 |
- keyword参数
搜索内容
Soup.find_all(id=’link2′,href=re.compile(“elsie”)) | 多个参数,同时过滤多个属性 |
有时候会碰到html或python的关键词,就可以加个下划线或者用一个dic来储存它,再进行搜索
- text参数
- 搜索文档中的字符串内容和name参数类似,可以接受字符串,正则表达式,列表,True。
soup.find_all(text=”Elsie”) | #[u’Elsie’] |
- limit参数
Find_all ()搜索返回所有的值,name文档树会很大,这时候就可以用limit参数限制返回结果的数量。 效果就和SQL中的limit关键字类似,
soupfind_all(“a”,limit=2) | 这里有三个符合的tag,结果只会返回两个,因为限制了返回数量 |
- Recusive 参数
tag的find_all会检索所有子孙节点,如果只想搜索tag的直接子节点,就可以使用参数recusive=False。
Soup.html.find_all(“title”) | #[<title>The Dormouse’s story</title>] |
Soup.html.find_all(“title”,recusive=False) | #[] |
(2)find(name,attrs,recusive.text,**kwargs)
find和find_all的唯一区别:find_all()返回的是包含元素的列表,而find()直接返回结果
(3)find_parents() find_parent()
find_all()和find()只搜索所有的子孙节点,而这两个就是搜索所有的父节点
(4)find_next_siblings() find_next_sibling() find_previous_siblings() find_previous_sibling()
对之前或之后的兄弟节点进行迭代,有s的返回所有符合节点,没有加s的返回最先检索到的那个节点
(5)find_all_next() find_next() find_all_previous() find_previous()
用法和(4)类似。
CSS选择器:
写css的时候,标签名不加任何修饰,类名前加点,id名前加#,在这里我们也可以利用类似的方法来筛选元素,用到的是soup.select(),返回的是list
(1)通过标签名查找。
Print soup.select(‘title’) | 返回的是title标签 |
(2)通过类名查找
print soup.select(‘ .sister’) | 返回的是类名是sister的tag |
(3)通过id名查找
Print soup.select(‘#link1’) | 返回的是id是link1的tag |
(4)组合查找
Print soup.select(‘p #link1’) | |
Print soup.select(“head > title”) | 子标签查找 |
(5)属性查找
属性查找的属性要用中括号括起来
也可以和上面的方法一起用,用空格空开来查找指定节点内的tag
Print soup.select(‘a[class=”sister”]’) | 查找a标签并且有class元素的tag |
Print soup.select(‘p a[href=”http://asd.com”]’) | p节点内有href的a的tag |
PS:select查找的结果都是list形式,可以遍历输出,然后get_text()方法来获取它的内容。(这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()