Python-BeautifulSoup4 学习笔记

安装BeautifulSoup

# 安装bs4
# 官网地址 https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#name
pip install beautifulsoup4
# 安装解析器 Python标准库自带Html解析器
pip install lxml
pip install html5lib

使用

实验网页


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <div style="height: 400px;background-color: whitesmoke;margin: 0 auto;">
        <h2 style="text-align: center;padding-top: 15px;">志研网h2>
        <div style="margin: 0 auto;background-color: white;height: 200px;width: 500px;border: 1px solid rgb(172, 172, 172);">
            <h3 style="border-bottom: 1px solid  rgb(172, 172, 172);height: 40px;line-height: 40px;margin-top: 0;padding-left: 25px;">注册验证h3>
            <p class="P1" id="S" style="margin-left: 25px;color:steelblue;">你好! [email protected]p>
            <p style="margin-left: 25px;color:steelblue;">欢迎注册志研网,请将注册码填到相应页面p>
            <p style="margin-left: 25px;color:steelblue;">您的验证码是:965341p>
            <p style="margin-left: 25px;color:gray;">@ginet.comp>
        div>
    div>
body>
html>

基本使用

# 引入bs4
from bs4 import BeautifulSoup
# 打开index.html
soup = BeautifulSoup(open("index.html", encoding='UTF-8'))
# 获取标签

的内容 默认第一个
tag = soup.p # 打印该标签 print(tag) # 标签类型 print(type(tag)) # 标签名 print(tag.name) # 修改名 tag.name = "blockquote" print(tag) # 打印标签的class名 print(tag['class']) # 打印标签所有属性 print(tag.attrs) # 打印标签的id print(tag['id']) # 删除属性 del tag['class'] del tag['id'] <p class="P1" id="S" style="margin-left: 25px;color:steelblue;">你好! yanggeol@qq.com</p> <class 'bs4.element.Tag'> p <blockquote class="P1" id="S" style="margin-left: 25px;color:steelblue;">你好! yanggeol@qq.com</blockquote> ['P1'] { 'class': ['P1'], 'id': 'S', 'style': 'margin-left: 25px;color:steelblue;'} S

多值属性

# tag转换成字符串时,多值属性会合并为一个值
rel_soup = BeautifulSoup('

Back to the homepage

'
) rel_soup.a['rel'] # ['index'] rel_soup.a['rel'] = ['index', 'contents'] print(rel_soup.p) #

Back to the homepage

# 转换的文档是XML格式,那么tag中不包含多值属性 xml_soup = BeautifulSoup('

'
, 'xml') xml_soup.p['class'] # u'body strikeout'

打印标签的字符串

from bs4 import BeautifulSoup


soup = BeautifulSoup(open("index.html", encoding='UTF-8'))

tag = soup.p

print(tag.string)
# 你好! [email protected]

# 不能编辑但可以替换字符串内容
tag.string.replace_with("No longer bold")

print(tag.string)

# tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None 

遍历文档树

tag的属性

from bs4 import BeautifulSoup


soup = BeautifulSoup(open("index.html", encoding='UTF-8'))

# 打印head
print(soup.head)
# 打印标题
print(soup.title)
# 打印body下第一个p
print(soup.body.p)
# 获取当前第一个p
print(soup.p)
# 获取所有p
print(soup.find_all('p'))
# 将head的子节点以列表的方式输出
print(soup.head.contents)
print(soup.head.contents[0])

tag = soup.head
print(tag.contents[1].name)
# 通过tag的 .children 生成器,可以对tag的子节点进行循环
for child in tag.children:
    print(child)
# .descendants 属性可以对所有tag的子孙节点进行递归循环 包含字符串
for child in tag.descendants:
    print(child)

# tag中包含多个字符串,可以使用 .strings 来循环获取
for string in soup.strings:
    print(repr(string))
# 输出的字符串中可能包含了很多空格或空行,使用 .stripped_strings 可以去除多余空白内容
for string in soup.stripped_strings:
    print(repr(string))
# 全部是空格的行会被忽略掉,段首和段末的空白会被删除


节点

父节点

from bs4 import BeautifulSoup

soup = BeautifulSoup(open("index.html", encoding='UTF-8'))

tag = soup.h3

print(tag)
 # .parent 属性来获取某个元素的父节点
print(tag.parent)

# 

注册验证

#
#

注册验证

#
# BeautifulSoup 对象的 .parent 是None: # 通过元素的 .parents 属性可以递归得到元素的所有父辈节点 for parent in tag.parents: if parent is None: print(parent) else: print(parent.name)

兄弟节点

# .next_sibling 和 .previous_sibling 属性来查询兄弟节点:
# 实际文档中的tag的 .next_sibling 和 .previous_sibling 属性通常是字符串或空白. 
from bs4 import BeautifulSoup

soup = BeautifulSoup(open("index.html", encoding='UTF-8'))

tag = soup.p
print(tag.previous_sibling.previous_sibling)
print(tag.next_sibling.next_sibling)

# 结果
# 

注册验证

#

欢迎注册志研网,请将注册码填到相应页面

# .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出

回退和前进

# .next_element 属性指向解析过程中下一个被解析的对象(字符串或tag)
# .previous_element 属性刚好与 .next_element 相反,它指向当前被解析的对象的前一个解析对象
# 通过 .next_elements 和 .previous_elements 的迭代器就可以向前或向后访问文档的解析内容,就好像文档正在被解析一样

from bs4 import BeautifulSoup


soup = BeautifulSoup(open("index.html", encoding='UTF-8'))

tag = soup.p

print(tag.previous_element)
print(tag.next_elements)

过滤器

# 用于查找文档中所有的标签
soup.find_all('b')

# 找出所有以b开头的标签,这表示和标签都应该被找到
import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
    
# 如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.
soup.find_all(["a", "b"])

# True 可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
for tag in soup.find_all(True):
    print(tag.name)

# 如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')
soup.find_all(has_class_but_no_id)

find_all

find_all(name, attrs,recursive,text, **kwargs)
# name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉.
soup.find_all("title")
# 如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.
# 搜索指定名字的属性时可以使用的参数值包括 字符串 , 正则表达式 , 列表, True .
# 使用多个指定名字的参数可以同时过滤tag的多个属性
soup.find_all(id='link2')
# 有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性
# 但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag
data_soup.find_all(attrs={
     "data-foo": "value"})

# 通过 class_搜索CSS类名
# class_ 参数同样接受不同类型的 过滤器 ,字符串,正则表达式,方法或 True
soup.find_all("a", class_="sister")
# 搜索 class 属性时可以通过CSS值完全匹配
# 完全匹配 class 的值时,如果CSS类名的顺序与实际不符,将搜索不到结果

# 通过 text 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表, True
soup.find_all("a", text="Elsie")

# find_all() 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果.
soup.find_all("a", limit=2)

# 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False
soup.html.find_all("title", recursive=False)

# find_all() 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法. BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all() 方法相同,下面两行代码是等价的
soup.find_all("a")
soup("a")

find

find(name, attrs,recursive,text, **kwargs)
# 找寻一个满足条件的

find_parents 和 find_parent

find_all()find() 只搜索当前节点的所有子节点,孙子节点等.

find_parents()find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容

find_next_siblings 和 find_next_sibling

find_next_siblings() 方法返回所有符合条件的后面的兄弟节点

find_next_sibling() 只返回符合条件的后面的第一个tag节点

find_previous_siblings 和 find_previous_sibling

find_previous_siblings() 方法返回所有符合条件的前面的兄弟节点

find_previous_sibling() 方法返回第一个符合条件的前面的兄弟节点:

find_all_next 和 find_next

find_all_next() 方法返回所有符合条件的节点

find_next() 方法返回第一个符合条件的节点

find_all_previous 和 find_previous

find_all_next() 方法返回所有符合条件的节点

find_next() 方法返回第一个符合条件的节点

CSS选择器

# Beautiful Soup支持大部分的CSS选择器,在 Tag 或 BeautifulSoup 对象的 .select() 方法中传入字符串参数,即可使用CSS选择器的语法找到tag
soup.select("title")
# 通过tag标签逐层查找
soup.select("body a")
# 找到某个tag标签下的直接子标签
soup.select("head > title")
# 找到兄弟节点标签
soup.select("#link1 ~ .sister")
# 通过CSS的类名查找
soup.select(".sister")
soup.select("[class~=sister]")
# 通过tag的id查找
soup.select("#link1")
soup.select("a#link2")
# 通过是否存在某个属性来查找
soup.select('a[href]')
# 通过属性的值来查找
soup.select('a[href="http://example.com/elsie"]')

修改文档树

# 修改 .string
tag.string = "New link text."
# Tag.append() 方法想tag中添加内容,就好像Python的列表的 .append() 方法
soup = BeautifulSoup("Foo")
soup.a.append("Bar")
# 如果想添加一段文本内容到文档中也没问题,可以调用Python的 append() 方法或调用工厂方法 BeautifulSoup.new_string()
soup.new_string(" there")
# 如果想要创建一段注释,或 NavigableString 的任何子类,将子类作为 new_string() 方法的第二个参数传入
soup.new_string("Nice to see you.", Comment)
# 创建一个tag最好的方法是调用工厂方法 BeautifulSoup.new_tag()
soup.new_tag("a", href="http://www.example.com")
# Tag.insert() 方法与 Tag.append() 方法类似,区别是不会把新元素添加到父节点 .contents 属性的最后,而是把元素插入到指定的位置.与Python列表总的 .insert() 方法的用法下同
tag.insert(1, "but did not endorse ")
# insert_before() 方法在当前tag或文本节点前插入内容
soup.b.string.insert_before(tag)
# insert_after() 方法在当前tag或文本节点后插入内容
# Tag.clear() 方法移除当前tag的内容
tag.clear()
# PageElement.extract() 方法将当前tag移除文档树,并作为方法结果返回 方法实际上产生了2个文档树
markup = 'I linked to example.com'
soup = BeautifulSoup(markup)

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

a_tag
# I linked to
i_tag
# example.com

print(i_tag.parent)
None


# Tag.decompose() 方法将当前节点移除文档树并完全销毁
soup.i.decompose()
# PageElement.replace_with() 方法移除文档树中的某段内容,并用新tag或文本节点替代它
a_tag.i.replace_with(new_tag)
# PageElement.wrap() 方法可以对指定的tag元素进行包装,并返回包装后的结果
soup.p.string.wrap(soup.new_tag("b"))
# Tag.unwrap() 方法与 wrap() 方法相反.将移除tag内的所有tag标签,该方法常被用来进行标记的解包
a_tag.i.unwrap()

输出

# prettify() 方法将Beautiful Soup的文档树格式化后以Unicode编码输出,每个XML/HTML标签都独占一行
# BeautifulSoup 对象和它的tag节点都可以调用 prettify() 方法
soup.prettify()
soup.a.prettify()
# 如果只想得到结果字符串,不重视格式,那么可以对一个 BeautifulSoup 对象或 Tag 对象使用Python的 unicode() 或 str() 方法
# str() 方法返回UTF-8编码的字符串,可以指定编码的设置
str(soup)
unicode(soup.a)
# Beautiful Soup输出是会将HTML中的特殊字符转换成Unicode,

# 如果只想得到tag中包含的文本内容,那么可以用 get_text() 方法,这个方法获取到tag中包含的所有文版内容包括子孙tag中的内容,并将结果作为Unicode字符串返回
soup.get_text()
# 可以通过参数指定tag的文本内容的分隔符
soup.get_text("|")
# 可以去除获得文本内容的前后空白
soup.get_text("|", strip=True)

你可能感兴趣的:(Python,python)