说明一下,这个标题可能有点突兀,结合上一篇一起看就行
前面已经对BeautifulSoup有了了解了,相信你基本已经学会怎么获取网页数据了,那么BeautifulSoup这么吊,还有没有其他的功能呢?当然是有的
前面说的Tag对象都还记得吧?像这样BeautifulSoup.title,得到的就是Tag对象,它其实还有一些属性:
还是前面的例子:
# -*- coding:utf-8 -*- import bs4 html=''' <html> <head> <title>这是第二节课</title> <meta charset='utf-8'> <!--meta是单标签--> <meta name='keywords' content='hello world,oh yeah'> </head> <!--<body bgcolor='green'>--> <body link='red' vinlk='green' alink='blue'> <h1>这是一个标题</h1> <!--超链接必须加上http://不然无法跳转--> <a href='http://www.baidu.com'>百度</a> <a href='http://www.163.com'>网易</a> <a href='http://www.qq.com'>腾讯</a> <a href='http://www.sina.com'>新浪</a> </body> </html> ''' test=bs4.BeautifulSoup(html,'html.parser') print test.title print test.title.contents
结果:
字符型是utf-8,而我用的是python2,前面编码问题已经说过了,略过
既然是列表对吧,那么它就可以使用列表的方法了:
既然是迭代器,那么就可以迭代出来了:
其实BeautifulSoup对象也有类似tag对象的children的属性:
同样的,使用for循环也可以迭代出来,这里直接略过。
上面的contents和children是什么属性呢?官方文档里有个称呼叫Tag对象的直接子节点。而descendants是BeautifulSoup的子孙节点。
既然有节点,结合上一篇说的,我们可以在Tag对象下使用string子节点属性获得html代码内的字符串内容,那么这样的内容就叫节点内容
我相信,你在自己动手练习时,一定遇到这种情况:
怎么是None呢?html里不是有数据title标签和meta标签等的吗?对吧?那么这为何是空呢?这里就是string属性的一个特性而来。
官方文档是这么说的:
如果tag只有一个NavigableString类型(忘记什么是NavigableString类型回去看上一篇博文)子节点,那么这个tag可以使用string属性得到子节点。如果一个tag仅有一个子节点,那么这个tag也可以使用string属性,输出结果与当前唯一子节点的string属性结果相同。
换句话就是:
如果一个标签里面没有子标签了,那么 string属性就会返回标签里面的内容。如果标签里面只有唯一的一个子标签了,那么string属性也会返回最里面的内容如果tag包含了多个子节点(子标签),tag就无法确定string属性应该调用哪个子节点的内容而返回None
那有朋友说,我就想返回多个内容怎么办?使用strings属性和stripped_strings属性
遍历就直接略过了,你使用工程函数list转为列表或者用for迭代或者转为字符串或者使用函数repr输出都随便你了
因为只返回字符串内容,而我那个html源码例子里属于head标签的只有这一句字符串内容,所以结果如上。
那么既然有子节点,自然还有父节点,前后节点,兄弟节点等等的。
使用parent属性会打印父级节点所有内容,使用parent.name属性则显示父级节点的名字
当然你会想,还有和父级节点同级的节点
同parents,略过
实际文档中的tag的 .next_sibling 和 .previous_sibling 属性通常是字符串或空白,因为空白或者换行也可以被视作一个节点,所以得到的结果可能是空白或者换行。
可以利用next_sibling.next_sibling获得下一个兄弟节点:
当然上一个兄弟节点也同样,略过
既然BeautifulSoup这么强大,那么也可以搜索文档内容吧?是的
1)name参数可以是一个字符串对象,即html标签
2)name参数可以是一个正则表达式,BeautifulSoup对象会默认使用正则表达式的match()方法匹配
这个就厉害了对吧?
3)name参数可以是一个列表,BeautifulSoup对象会将与列表中任一元素匹配的内容返回
4)name参数可以是Bool函数的True,True即代表可以匹配任何值(即所有值)
5)name参数可以是一个函数/方法
自定义了一个has方法,只返回拥有href属性的标签
keyword参数
如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索如果包含一个名字为id的参数,BeautifulSoup对象会搜索每个tag的”id”属性
1)如果参数是id:
由于前面的html标签里没有适合的标签,所以这里新设一个例子
txt='<a class="yang" href="http://example.com" id="link">test</a>' test1=bs4.BeautifulSoup(txt,'html.parser') print test1.find_all(id='link')
结果:
2)如果参数是href:
还是原来的例子
当然你可以使用多个指定名字的参数可以同时过滤tag的多个属性。略过
注意:
当关键词是class时,由于class也是python的关键词语句,当作关键词使用时,使用【class_】就行当遇到特殊情况不能被搜索时,可以使用attrs参数定义一个字典参数来搜索包含特殊属性的tag不过以上情况基本少见,略过
text参数:可以搜索文档中的字符串内容,与name参数的可选值一样,可以是字符串 , 正则表达式 , 列表, True
略过
limit参数:如果文档很大那么搜索会很慢,而我们并不需要全部结果,使用limit参数限制返回结果的数量,效果与SQL中的limit关键字类似,当搜索到的结果数量达到limit的限制时,就停止搜索返回结果。
limit参数在很多地方都有用到
本来html代码里有四个a标签,设置limit参数后只得到两个值
recursive参数:recursive值默认为True,即BeautifulSoup对象会默认检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数recursive=False
使用与不使用的差别
14.还有以下这些方法,使用基本和find_all类似,所以直接略过:
find( name,attrs, recursive, text, **kwargs ): 类似find_all(),不过find() 方法直接返回结果
find_parents()和find_parent()
find_all() 和 find()只搜索当前节点的所有子节点,孙子节点等。find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容
find_next_siblings()和find_next_sibling()
这2个方法通过next_siblings 属性对当 tag 的所有后面解析的兄弟 tag 节点进行迭代, find_next_siblings() 方法返回所有符合条件的后面的兄弟节点,find_next_sibling() 只返回符合条件的后面的第一个tag节点
find_previous_siblings()和find_previous_sibling()
这2个方法通过previous_siblings 属性对当前 tag 的前面解析的兄弟 tag 节点进行迭代, find_previous_siblings() 方法返回所有符合条件的前面的兄弟节点, find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点
find_all_next()和find_next()
这2个方法通过next_elements 属性对当前 tag 的之后的 tag 和字符串进行迭代, find_all_next() 方法返回所有符合条件的节点, find_next() 方法返回第一个符合条件的节点
find_all_previous() 和 find_previous()
这2个方法通过previous_elements 属性对当前节点前面的 tag 和字符串进行迭代, find_all_previous() 方法返回所有符合条件的节点, find_previous()方法返回第一个符合条件的节点
那有朋友说,假如html代码里有css样式表等使用符号【#】的又怎么处理呢?
可以对css样式表查询,返回列表对象
那个常用例子并没有class的,所以另设一个例子
txt='<a class="yang" href="http://example.com" id="link"><!-- test --></a>' test1=bs4.BeautifulSoup(txt,'html.parser') print test1.select('.yang')结果:
与通过class查找一样:
txt='<a class="yang" href="http://example.com" id="link"><!-- test --></a>' test1=bs4.BeautifulSoup(txt,'html.parser') print test1.select('#link')结果:
组合使用标签名与类名、id名进行查找,和单独查找原理一样,注意不在同一节点的空格隔开,同一节点的不加空格。详细的略过
原来的例子:
可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到
属性查找同样可以与上面的查找方式组合,不在同一节点的空格隔开,同一节点的不加空格
注意:
select()返回的既然是列表,那么可以运用所有符合列表的方法,自己去发现了利用select()可以达到同find_all效果相同
内容比较多,其实官方的文档都还有些,不过那些基本不怎么用了,所以就这些吧,只有查找提取的方法,这已经完完全全的够用了
转载于:https://www.cnblogs.com/Eeyhan/p/7814108.html