BeautifulSoup操作大全


 1 一、获取BeautifulSoup文档的对象
 2     1.对象
 3         Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,
 4         所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .
 5         
 6         Comment 对象是一个特殊类型的 NavigableString 对象,其输出的内容不包括注释符号。
 7             
 8             <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
 9             #a 标签里的内容实际上是注释,但是如果我们利用 .string 来输出它的内容时,注释符号已经去掉了。
10             type(soup.a.string)  -->   <class 'bs4.element.Comment'>
11             
12             
13         可以传入一段字符串或一个文件句柄.
14         from bs4 import BeautifulSoup
15         soup = BeautifulSoup(open("index.html"))   or    soup = BeautifulSoup("<html>data</html>")    
16     2.编码
17         使用Beautiful Soup解析后,文档都被转换成了Unicode
18         Beautiful Soup用了 编码自动检测 子库来识别当前文档编码并转换成Unicode编码.
19         BeautifulSoup 对象的 .original_encoding 属性记录了自动识别编码的结果
20         
21         #通过传入 from_encoding 参数来指定编码方式
22         soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
23         
24         #节点可通过encode() 方法来指定输出编码
25         soup.p.encode("utf-8")
26         
27         #通过Beautiful Soup输出文档时,不管输入文档是什么编码方式,输出编码均为UTF-8编码
28         print(soup.prettify("latin-1"))   #如果不想用UTF-8编码输出,可以将编码方式传入 prettify() 方法
29         prettify() #增加换行符,html格式打印
二、Tag对象属性
    name 
    attrs  返回一个字典    例如:{'class':'sister'}  #可以操作字段
        def __getitem__(self, key):   return self.attrs[key]
        def has_attr(self, key):    key in self.attrs
    contents
        注意 空格换行等 都包含在contents内
        def __len__(self): return len(self.contents)
        def __contains__(self, x): return x in self.contents
        def __iter__(self): return iter(self.contents)
    string       
            child = self.contents[0]
            if isinstance(child, NavigableString):  #如果tag.contents[0] 为 NavigableString 类型子节点,直接得到子节点
                return child
            return child.string  #如果不是 则获取子标签的string属性
    children 
        ==  iter(self.contents)
    next_element 和 previous_elemen
        如同字面意思,前一个ele和后一个ele
        next_elements 和 previous_elements
            当前Tag前面和后面ele的迭代器
    descendants
        迭代器,从contents[0] 然后.next_element直到.next_sibling.previous_element        
    strings 和 stripped_strings  
        迭代器
        for descendant in self.descendants:
            strings --> 遍历descendants属性,获取所有NavigableString对象
            stripped_strings  --> 遍历descendants属性,获取所有len(descendant.strip()) != 0 的 NavigableString对象
    parent 和 parents
        parent:元素的父节点
        parents:迭代器一直获取.parent属性  
    next_sibling 和 previous_sibling
        查询兄弟节点
        实际文档中的tag的 .next_sibling 和 .previous_sibling 属性通常是字符串或空白
        next_siblings 和 previous_siblings 属性可以对当前节点的兄弟节点迭代输出
三、通过API获取Tag对象
    一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.
    1.根据标签查找(type:bs4_obj)
        tag_p = soup.p  #返回HTML文档第一个Tag p标签
    
    2.通过 find 和 find_all
        find(name=None, attrs={}, recursive=True, text=None, **kwargs) 
        #内部调用find_all方法返回第一个Tag    
        find_all(self, name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
        #recursive=True 默认会检索当前tag的所有子孙节点,参数 recursive=False 只检索子节点
        #limit参数 限制返回数量
        
        #名字为 name 的tag,如果name不是内置的参数名,搜索时会按tag的属性来搜索注意class的写法
        soup.find_all("title") or soup.find_all(class_ = 'tb')  or  soup.find_all(id='link2')  
        
        soup.find_all("a", class_="sister") or soup.find_all("a", attrs={"class": "sister"})
        #class_ 参数同样接受不同类型的 过滤器 ,字符串,正则表达式,方法或 True
        soup.find_all(class_=re.compile("itl"))
        def has_six_characters(css_class):
            return css_class is not None and len(css_class) == 6
        soup.find_all(class_=has_six_characters)  # 过滤其class属性长度为6的标签
        # text 参数可以搜搜文档中的字符串内容,接受 字符串 , 正则表达式 , 列表, True .
        soup.find_all(text=re.compile("Dormouse"))
        soup.find_all("a", text="Elsie")   #包含“Elsie”的<a>标签
        soup.find_all(text="Elsie")  #返回一个NavigableString对象
        
        #实际上就是对 .children 属性的迭代搜索
    3.通过soup()
        内部调用find_all方法
        def __call__(self, *args, **kwargs):    return self.find_all(*args, **kwargs)
    4.通过find_parents() 和 find_parent()
        find_parent(self, name=None, attrs={}, **kwargs)  #搜索当前节点的第一个父节点
        find_parents(self, name=None, attrs={}, limit=None, **kwargs) #搜索当前节点的所有父节点,父父节点等
        #实际上就是对 .parents 属性的迭代搜索
    5.通过find_previous_siblings() 和 find_previous_sibling(): #一个与多个(list)
        find_previous_siblings(self, name=None, attrs={}, text=None, limit=None, **kwargs)
        #实际上就是对 .previous_siblings 属性的迭代搜索
    6.通过find_all_next() 和 find_next():
        find_all_next(self, name=None, attrs={}, text=None, limit=None, **kwargs)
        #实际上就是对 .next_elements 属性的迭代搜索
    7.通过find_all_previous() 和 find_previous():
        find_all_previous(self, name=None, attrs={}, text=None, limit=None, **kwargs)
        #实际上就是对 .previous_elements 属性的迭代搜索
四、通过CSS选择器获取Tag对象
    (1)通过标签名查找:
        soup.select('a')  #返回所有的a标签  list
    (2)通过类名查找:
        soup.select('.sister') #返回所有包含class="sister"的标签  list
        soup.select('a.sister')
    (3)通过 id 名查找:
        soup.select('#link1')  #返回所有包含 id="link1"的标签  list
        soup.select("p#link1")
    (4)组合查找:
        soup.select('p #link1')  #查找所有 p 标签中,id 等于 link1的标签  注意区分soup.select('p#link1')
        soup.select("html head title") or soup.select("body a")   #逐层查找    
        soup.select("p > a")  #直接子标签查找  注意是子标签不是子孙标签
    (5)通过是否存在某个属性和属性的值来查找:
        soup.select('a[href]')
        soup.select('a[href="http://example.com/elsie"]')
        soup.select('a[href^="http://example.com/"]')    #  ^=  开头
        soup.select('a[href$="tillie"]')                #  $=  结尾
        soup.select('a[href*=".com/el"]')               #  *=  包含
五、解析部分文档
    将整片文档进行解析,实在是浪费内存和时间.最快的方法是从一开始就把想要获取以外的东西都忽略掉.
    SoupStrainer 类可以定义文档的某段内容,这样搜索文档时就不必先解析整篇文档。
    三种SoupStrainer 对象:
        from bs4 import SoupStrainer
        only_a_tags = SoupStrainer("a")  #把<a>标签以外的东西都忽略掉
        
        only_tags_with_id_link2 = SoupStrainer(id="link2") #把属性id="link2"标签以外的东西都忽略掉
        
        def is_short_string(string):
            return len(string) < 10
        only_short_strings = SoupStrainer(text=is_short_string) #把文本内容长度大于等于10的标签都忽略掉
    
    将 SoupStrainer 对象作为 parse_only 参数给 BeautifulSoup 的构造方法即可
        print(BeautifulSoup(html_doc, "html.parser", parse_only=only_a_tags).prettify())

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM