基础学习——BeautifulSoup篇(2)

这一篇文章接在上一篇 基础学习——BeautifulSoup篇(1) 之后,今天来继续学习BeautifulSoup

欢迎关注公众号:老白和他的爬虫

4.遍历文档树

4.7父节点和兄弟节点

父节点可以通过.parent.parents操作得倒

from bs4 import BeautifulSoup
if __name__ == "__main__":
     html_doc = """
        The Dormouse's story
        

The Dormouse's story

Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well.

...

""" soup = BeautifulSoup(html_doc,'lxml') head_tag = soup.head title_tag = head_tag.contents[0] print(title_tag.parent) #打印title_tag的父节点 link = soup.a for parent in link.parents: #循环打印a标签的父节点 if parent is None: print(parent) else: print(parent.name)

兄弟节点些微有点不同,一个节点可以通过.next_sibling.previous_sibling得到它之前和之后的兄弟节点,同样,也可以通过.next_siblings.previous_siblings遍历操作得倒所有的兄弟节点。

4.8回退和缩进

上一个内容讲的.next_sibling.previous_sibling其实就已经有了缩进和回退的味道了,但是他们是不同的。我们使用解析器把html文档解析成了一个又一个事件或者说是标签,兄弟节点只能在这一级进行前后操作,然而要对整个文档进行操作,我们就必须使用到.next_element.previous_element。我们用上面的文档树来举一个例子

last_a_tag = soup.find("a", id="link2")
print(last_a_tag.next_sibling) 
print(last_a_tag.next_element) 

print(last_a_tag.next_sibling)的输出结果是and因为第二个下一个兄弟节点是and,但是print(last_a_tag.next_element)的输出结果是Lacie,因为第二个下一个元素是比它低一级的字符串Lacie。这段代码理解的画,这两个操作也很好理解了,同理它还有.next_elements.previous_elements这两个操作,具体怎么用不用我说了吧,类比一下就会了。

4.9. find_all()

find_all(name , attrs , text , keyword )使用.find_all()操作可以设置这些常用参数

4.9.1 name参数

.find_all()可以直接查找tag的name来找到对应的标签

soup.find_all('b') #用来查找所有的标签

4.9.2 keyword参数.find_all()``.find_all()

print(soup.find_all(id='link2')) #用来查找id为link2的标签

.find_all()操作可以与正则表达式搭配,个人认为这一步在查找一些特定标签时十分有用

import re
     #找到所有标签中以b开头的标签
     for tag in soup.find_all(re.compile("^b")):
         print(tag.name)
     #提取所有a标签中包含字符串example的链接
     for x in soup.find_all('a',href = re.compile('example')):
         print(x.get('href'))

这里记住一点,.find_all()内部的多个参数是可以同时写的,上面这段代码我这样写也可以

for x in soup.find_all(class_ = 'sister' ,href = re.compile('example')):
         print(x.get('href'))

class应该是python的关键字,所以我们这里需要用class_来表示class

4.9.3 attrs参数

可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag

data_soup = BeautifulSoup('
foo!
','lxml') print(data_soup.find_all(attrs={"data-foo": "value"}))

4.9.4 text参数

     print(soup.find_all(text="Elsie")) #输出文本为Elsie的字符串
     print(soup.find_all(text=["Tillie", "Elsie", "Lacie"])) #输出文本为列表中所包含的字符串
     print(soup.find_all(text=re.compile("Dormouse"))) #输出文本包含Dormouse的字符串

4.9.5 limit参数

limit参数可以限制返回节点的数量

    print(soup.find_all('a',limit = 2)) #本身可以返回三个a标签,但是由于limit限制只返回两个

4.10 find()

.find()其实就是.find_all()加上了limit = 1的操作,区别于.find()返回的是结果,.find_all()返回的是集合
.find().find_all()还有其他的一些操作,这里就不一一举例了,避免这个教程太过繁琐,只要熟练的掌握.find().find_all(),就已经能解决很多的问题。其他的一些操作包括
find_parents(),find_parent(),find_next_siblings(),find_next_sibling(),find_previous_siblings(),find_previous_sibling(),find_all_next(),find_next(),find_all_previous(),find_previous()

4.11 CSS选择器

这一个功能我不打算在这里说,因为这里能实现的功能在前面我们都已经实现了,只不过更熟悉css的人可以选择这种方法。

5.修改文档树

给tag的 .string属性赋值,就相当于用当前的内容替代了原来的内容:

     markup = 'I linked to example.com'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     tag.string = "New link text."
     print(tag)

使用.append()方法可以像标签添加内容

     markup = 'I linked to '
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     print(tag)
     tag.append("haha")
     print(tag)

如果想要创建一段注释

     from bs4 import Comment
     new_comment = soup.new_string("Nice to see you.", Comment)
     tag.append(new_comment)
     print(tag)

如果想要创建一个新的tag

     soup = BeautifulSoup("",'lxml')
     original_tag = soup.b
     new_tag = soup.new_tag("a", href="http://www.example.com")
     original_tag.append(new_tag)
     print(original_tag)
     new_tag.string = "Link text."
     print(original_tag)
    

使用'.insert()'插入具体的内容

     markup = 'I linked to example.com'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     tag.insert(1, "but did not endorse ") #参数1控制插入字符串的位置
     print(tag)

移除当前tag的内容

     tag.clear()
     print(tag)

移除当前的tag节点

     a_tag = soup.a
     i_tag = soup.i.extract()
     print(a_tag)
     print(i_tag)

使用decompose()完全销毁当前tag节点

     markup = 'I linked to example.com'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     a_tag = soup.a
     soup.i.decompose()
     print(a_tag)

使用replace_with()替换节点

     markup = 'I linked to example.com'
     soup = BeautifulSoup(markup,'lxml')
     tag = soup.a
     a_tag = soup.a
     new_tag = soup.new_tag("b")
     new_tag.string = "example.net"
     a_tag.i.replace_with(new_tag)
     print(tag)

6.输出

.prettify()方法将BeautifulSoup的文档树格式化后以Unicode编码输出,每个XML/HTML标签都独占一行

     markup = 'I linked to example.com'
     soup = BeautifulSoup(markup,'lxml')
     print(soup.prettify())

如果不想格式化输出,可以选择压缩输出

     print(str(soup))

如果只想得到标签中的文本内容

     markup = '\nI linked to example.com\n'
     soup = BeautifulSoup(markup,'lxml')
     print(soup.get_text())
     print(soup.get_text("|")) #指定文本分隔符
     print(soup.get_text("|", strip=True)) #去除文本内容前后空白

好了,BeautifulSoup的基础知识我们已经学习完毕了,你可以跟着这两篇文章来学习掌握BeautifulSoup,也可以选择把这两篇当作字典,当你在写爬虫时来翻阅

你可能感兴趣的:(基础学习——BeautifulSoup篇(2))