05BeautifulSoup traverse the document book and search the document tree

BeautifulSoup

First, what is BeautifulSoup

BS4 is a resolver library, you can extract the data we want to help by some parser

Second, why use BS4

Because he can quickly extract the contents of the user wants to use simple syntax

Third, the installation

# 安装BeautifulSoup4
pip3 install beautifulsoup4

# 安装解析器
# 根据官网解释,推荐使用lxml
pip3 install lxml

Fourth, the basic use

from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="sister"><b>$37</b></p>

<p class="story" id="p">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" >Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc,'lxml')
#自动补全html标签功能
print(soup)

html_doc = soup.prettify()
print(html_doc)

V. traverse the document tree

from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="sister"><b>$37</b></p>

<p class="story" id="p">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" >Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc,'lxml')
#     1、直接使用
print(soup.html)
print(type(soup.html)) #类型变成了element_tag
print(soup.a)
#     2、获取标签的名称
print(soup.a.name)
#     3、获取标签的属性
print(soup.a.attrs)
#     4、获取标签的内容
print(soup.p.text)
#     5、嵌套选择
print(soup.html.body.p)
#     6、子节点、子孙节点
print(soup.p.children)
#     7、父节点、祖先节点
print(soup.b.parent)
print(soup.b.parents)
#返回一个生成器
# 生成器:
def f():
    yield 1
    yield 2
    yield 3
    #把值放在生成器中

g=f() #expected results :<generator object parents at 0x000001C03E19E308>

for line in g:
    print(line)
#expected results 1 2 3
#      8、兄弟节点  (sibling: 兄弟姐妹)
print(soup.a)
# 获取下一个兄弟节点
print(soup.a.next_sibling)
# 获取下一个的所有兄弟节点,返回的是一个生成器
print(soup.a.next_siblings)
print(list(soup.a.next_siblings))

# 获取上一个兄弟节点
print(soup.a.previous_sibling)
# 获取上一个的所有兄弟节点,返回的是一个生成器
print(list(soup.a.previous_siblings))

Sixth, the document tree search

标签查找与属性查找:
    find与findall
    find找一个
    findall找所有
    标签:
        - 字符串过滤器   字符串全局匹配
            name 属性匹配
            attrs 属性查找匹配
            text 文本匹配
    
        - 正则过滤器
            re模块匹配
    
        - 列表过滤器
            列表内的数据匹配
    
        - bool过滤器
            True匹配
    
        - 方法过滤器
            用于一些要的属性以及不需要的属性查找。
        
    属性:
        - class_
        - id
from bs4 import BeautifulSoup
import re

# 注意: 如何初始文本内有换行,也会算在里面。(坑)
html_doc = """
<html><head><title>The Dormouse's story</title></head><body><p class="sister"><b>$37</b></p><p class="story" id="p">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" >Elsie</a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>and they lived at the bottom of a well.</p><p class="story">...</p>
"""


# 第一个参数是解析文本
# 第二个参数是解析器
soup = BeautifulSoup(html_doc, 'lxml')

'''
标签查找与属性查找:

    标签:
        - 字符串过滤器   字符串全局匹配
            name 属性匹配
            attrs 属性查找匹配
            text 文本匹配
    
        - 正则过滤器
            re模块匹配
    
        - 列表过滤器
            列表内的数据匹配
    
        - bool过滤器
            True匹配
    
        - 方法过滤器
            用于一些要的属性以及不需要的属性查找。
        
    属性:
        - class_
        - id
'''


# 1、字符串
# find的默认参数 第一个是name、第二个是attrs、第四个是text
# name: 根据标签名匹配节点
print(soup.find('p'))  # 获取第一个p标签
print(soup.find_all(name='p'))  # 获取所有的p标签

# attrs: 根据属性查找匹配节点
print(soup.find(attrs={'id': 'p'}))  # 查找id为p的标签
print(soup.find_all(attrs={'class': 'sister'}))  # 查找class为sister的所有标签

# text: 根据文本匹配文档树内的文本
# 推荐配合其他匹配规则使用,否则毫无意义
print(soup.find(text='$37'))  # 查找标签内为$37的文本

# name与text配合使用
print(soup.find_all(name='p', text='$37'))  # 查找所有文本为$37的p标签

# name与attrs配合使用
print(soup.find(name='a', attrs={'id': 'link2'}))  # 查找第一个id为link2的a标签

# attrs与text配合使用
print(soup.find_all(attrs={'id': 'link2'}, text='Lacie'))  # 查找所有id为link2,文本为Lacie的标签

# name、attrs、text组合使用
print(soup.find_all(name='a', attrs={'id': 'link3'}, text='Tillie'))  # 查找所有id为link3,文本为Tillie的a标签


# 2、正则
print(soup.find(name=re.compile('a')))  # 通过第一个标签名带有a的节点
print(soup.find_all(attrs={'id': re.compile('link')}))  # 匹配所有id名带有link的节点
print(soup.find_all(text=re.compile('and')))  # 匹配所有文本带有"and"的节点


# 3、列表 (列表内可以匹配多个)
print(soup.find_all(name=['a', re.compile('e')]))  # 匹配所有a标签节点与所有标签中带有e的节点
print(soup.find_all(text=['$']))  # 找不到,因为$是精确查找
print(soup.find_all(text=['$37']))  # 查找$37文本,这样查找是没有意义的
print(soup.find_all(text=[re.compile('\$')]))  # 正则中$是特殊字符,所以需要转义


# 4、bool
print(soup.find_all(name=True))  # 查找所有有标签名的节点
print(soup.find_all(attrs={'id': True}))  # 查找所有有id的节点
print(soup.find_all(text=True))  # 查找所有文本


# 5、方法
# 写一个只要有class没有id的a标签的函数
def has_class_not_id(arg):
    if arg.name == 'a' and arg.has_attr('class') and not arg.has_attr('id'):
        return arg.name

print(soup.find_all(name=has_class_not_id))  # 通过has_class_not_id的函数匹配节点


# 6、标签与属性查找
# 标签
print(soup.find_all(attrs={'class': 'sister'}))

# 属性
# 根据class属性查找,因为class是关键字,所以后面需要加下划线
print(soup.find_all(class_='sister'))
# 根据id属性查找
print(soup.find_all(id='link2'))

Guess you like

Origin www.cnblogs.com/Crystal-Zh/p/11127323.html