Python爬虫技术之Beautiful Soup相关最全详细技术

Beautiful Soup技术

一、基本过程

在这里插入图片描述
官方文档链接: Beautiful Soup官方文档

二、初始化Beautiful Soup对象

1、 从bs4库中导入BeautifulSoup类实例化一个对象

from bs4 import BeautifulSoup
soup = BeautifulSoup(markup,features)

1.2 其中两个参数的作用

1.2.1 markup
(1)解释

被解析的HTML字符串或文件内容

(2)两种使用方式
        使用字符串变量
#使用html_str字符串变量
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
        使用open( )函数打开文件
#假设将html_str字符串写入index.html
from bs4 import BeautifulSoup
soup = BeautifulSoup(open(index.html))
1.2.2 features
(1) 解释

解析器的类型

(2)两种使用方式
      指定解析器(BeautifulSoup选择指定的解析器来解析文档)
#指定lxml作为解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str,'lxml')
     未指定解析器(BeautifulSoup选择最默认的解析器来解析文档)
#解析html_str选择最默认的解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)

三、BeautifulSoup选择器

1、选择器分类

   节点选择器(获取数据的基本方法)
   方法选择器(查找、定位元素的常用选择)
   CSS选择器(查找、定位元素的常用选择)

2、选择器作用

   查找、定位元素、并获取数据

3、思维图

在这里插入图片描述

4、节点选择器

节点选择器就是使用tag对象来选择节点元素。而tag对象与HTML、XML的原生文档中的Tag相同,即标签。

<title>The Dorcument story</title>
<a href="...." id="...">Bob</a>

title和a标签里的内容成为Tag对象

#例如
print(soup.title)

4.1 格式

4.1.1 获取元素
       格式:soup.tag
       返回值:节点元素
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""

#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)

#3、定位元素title
print(soup.title)

#4、查看获取到的结果的类型 获取到的元素的类型是Tag类的对象
print(type(soup.title))

#5、当html中存在多个相同的节点的时候,只会提取第一个节点
print(soup.a)

4.2 提取信息的方法

4.2.1 获取名称
        格式:soup.tag.name
        返回值:字符串
#例一
#获取a标签的名字
soup.a.name

#输出结果
a
4.2.2 获取属性
        格式:  soup.tag.attrs
        返回值:   字典
#例二
#获取a标签的属性
soup.a.attrs

#输出结构
{'href':'http://exmaple.com','class':['sister'],'id':'link1'}
4.2.3 获取内容
      格式:soup.tag.string
      返回值:字符串
#例三
#获取a标签的内容
soup.a.string 

#输出结构
Bob

4.2.4 总体样例
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""

#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)

#3、获取a标签的名称
print(soup.a.name)

#4、查看a标签名称的类型
print(type(soup.a.name))

#5、获取a标签的属性
print(soup.a.attrs)

#6、获取a标签的值
print(soup.a.string)

4.3 嵌套选择的方法

格式:soup.tag.tag
返回值: 节点元素

html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""

#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)

#3、获取head的子节点title
print(soup.head.title)

#4、获取head的子节点title的类型
print(type(soup.head.title))

#5、获取head的子节点title的内容
print(soup.head.title.string)

4.4 关联选择的方法

在做选择的时候,有时候不能做到一步就选到想要的节点元素,需要先选中某一个节点元素,然后以他为基准再选择他的子节点、父节点、兄弟节点等。

4.4.1 子节点
         格式:soup.tag.contents
         返回值:   列表
          
         格式:soup.tag.children
         返回值:生成器
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""

#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)

#3、获取p标签的子节点
print(soup.p.contents)

#4、获取p标签的子节点children
print(soup.p.children)

for i,child in enumerate(soup.p.children):
    print(i,child)
4.4.2 父节点
        格式:soup.tag.parent
        返回值:  节点元素
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""

#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)

#3、获取a标签的父节点 parent
print(soup.a.parent)

#4、获取a节点的祖先节点 parents
print(soup.a.parents)

print(list(enumerate(soup.a.parents)))
4.4.3 兄弟节点
(1)获取后面一个节点
        格式:soup.tag.next_sibling
        返回值:  节点元素
(2)获取后面所有的节点
         格式:soup.tag.next_siblings
         返回值:  生成器
(3)获取前面一个节点
          格式:soup.tag.previous_sibling
           返回值:节点元素
(4)获取前面所有的节点
           格式:soup.tag.previous_siblings
           返回值:  生成器
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""

#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)

#3、获取a节点的兄弟节点 next_sibling
print(soup.a.next_sibling)

#4、获取a节点的所有兄弟节点 next_siblings
print(soup.a.next_siblings)

print(list(enumerate(soup.a.next_siblings)))

#5、获取a节点的前面一个节点 previous_sibling
print(soup.a.previous_sibling)

#6、获取a节点的前面的所有节点,previous_siblings
print(soup.a.previous_siblings)

print(list(enumerate(soup.a.previous_siblings)))

5、CSS选择器

主要分支和内容
在这里插入图片描述

5.1 获取元素

使用CSS选择器,只需要调用select( )方法,并结合CSS选择器语法就可以定位元素的位置。
格式:soup.select( )

5.2 CSS选择器语法

5.2.1 id选择器

id选择器需要使用#来定位元素,例如:获取第一个ul节点 #list-1

5.2.2 类选择器

类选择器需要使用 . 来定位元素,例如:获取所有的ul . list

5.2.3 标签选择器

标签选择器需要使用标签来进行选择,例如:获取h4

5.2.4 混合使用

获取第一个ul中的li节点 例如:.panel-body #list-1 li

html = '''
<div class="panel">
     <div class="panel-heading">
        <h4>Hello</h4>
     </div>
     <div class="panel-body">
          <ul class="list" id="list-1">
               <li class="element">Foo</li>
               <li class="element">Bar</li>
               <li class="element">Jay</li>
          </ul>
          <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
          </ul>
     </div>
</div>
'''


#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html)

#3、获取class="panel-heading"的div
print(soup.select(".panel .panel-heading"))

#4、获取所有的li节点 标签选择器
print(soup.select("ul li"))

#5、获取所有的li节点 类选择器
print(soup.select(".list .element"))

#6、获取第二个ul的li节点 id选择器
print(soup.select("#list-2 li"))

#7、获取第二个ul的li节点 类选择器
print(soup.select(".list-small li"))

#8、获取第二个ul节点 列表获取
print(soup.select("ul")[1])

5.3 CSS选择器高级用法

5.3.1 嵌套选择

先选择一个节点,再获取这个节点下面的子节点


html = '''
<div class="panel">
     <div class="panel-heading">
        <h4>Hello</h4>
     </div>
     <div class="panel-body">
          <ul class="list" id="list-1">
               <li class="element">Foo</li>
               <li class="element">Bar</li>
               <li class="element">Jay</li>
          </ul>
          <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
          </ul>
     </div>
</div>
'''


#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html)

#3、获取ul节点
print(soup.select("ul"))

#4、查看ul节点的类型
print(type(soup.select("ul")))

for ul in soup.select("ul"):
    print(ul)
    print(type(ul))
    print(ul.select("li"))
5.3.2 获取属性

css选择器获取属性的方法和节点选择器获取属性的方法一样,使用attrs属性来获取。


html = '''
<div class="panel">
     <div class="panel-heading">
        <h4>Hello</h4>
     </div>
     <div class="panel-body">
          <ul class="list" id="list-1">
               <li class="element">Foo</li>
               <li class="element">Bar</li>
               <li class="element">Jay</li>
          </ul>
          <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
          </ul>
     </div>
</div>
'''


#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html)

#3、获取li节点
print(soup.select("#list-2 li"))

for li in soup.select("#list-2 li"):
    print(type(li))
    print(li.attrs)
    print(li.attrs['class'])
5.3.3 获取文本

css选择器获取文本的方法和节点选择器获取文本的方法一样,使用string和strings属性来获取


html = '''
<div class="panel">
     <div class="panel-heading">
        <h4>Hello</h4>
     </div>
     <div class="panel-body">
          <ul class="list" id="list-1">
               <li class="element">Foo</li>
               <li class="element">Bar</li>
               <li class="element">Jay</li>
          </ul>
          <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
          </ul>
     </div>
</div>
'''


#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html)

#3、获取li节点
print(soup.select("#list-2 li"))

for li in soup.select("#list-2 li"):
    print(type(li))
    print(li.string)
    
#4、获取ul节点
print(soup.select("#list-2"))

for ul in soup.select("#list-2"):
    print(type(ul))
    print(ul.strings)
    print(list(ul.strings))

6、方法选择器

在这里插入图片描述

6.1 find_all( )方法

6.1.1 作用及范围
6.1.1.1 作用

用于搜索当前节点的所有符合条件的节点

6.1.1.2 范围

当前节点下的所有节点,如果没有指定当前节点,则进行全文的搜索

6.1.1.3 用法
find_all(name,attrs,recursive,text,**kwargs)
6.1.2 name参数
6.1.2.1 作用

查找所有名字为name的节点(tag对象)

6.1.2.2 参数形式
(1)字符串

传入一个字符串参数,即标签名(tag),Beautiful Soup会查找与字符串内容完全匹配的内容

#寻找所有span标签
print(soup.find_all(name="span"))

(2)正则表达式

传入正则表达式,Beautiful Soup会通过正则表达式的match( ) 函数来匹配内容

import re
for tag in soup.find_all(re.compile('^b')):
    print(tag.name)
(3) 列表

传入列表参数,Beautiful Soup会与列表中任一元素匹配,并返回结果

#使用列表选择包含a和span的所有标签
print(soup.find_all(['a','span']))
(4) True

True可以匹配任何值

#使用True选择文件中所有标签
for tag in soup.find_all(True):
    print(tag.name)
6.1.2.3 样例

html = '''
<div class="panel">
     <div class="panel-heading">
        <h4>Hello</h4>
     </div>
     <div class="panel-body">
          <ul class="list" id="list-1">
               <li class="element">
               <span>Foo</span>
               </li>
               <li class="element">Bar</li>
               <li class="element">Jay</li>
          </ul>
          <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
          </ul>
     </div>
</div>
'''


#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html)

#3、获取span标签 字符串
print(soup.find_all(name="span"))
    
#4、获取span标签  正则表达式  模型对象
import re
reg = re.compile('^sp')
print(soup.find_all(name=reg))

#5、获取a和span标签列表
print(soup.find_all(name=['a','span']))

#6、True的用法 递归的获取所有的标签
print(soup.find_all(name=True))
6.1.3 attrs参数
6.1.3.1 作用

查询含有接受的属性值的标签

6.1.3.2 参数形式

字典类型

#获取id为link1的标签
print(soup.find_all(attrs={id:'link1'}))
6.1.4 kwargs参数
6.1.4.1 作用

接收常用的属性参数,如id 和 class

6.1.4.2 参数形式

变量赋值的形式

#获取id为link1的标签
print(soup.find_all(id='link1'))
6.1.5 text参数
6.1.5.1 作用

查询含有接收的文本的标签

6.1.5.2 参数形式

字符串
通过搜索文档中的字符串内容,来确定文件标签

#获取文本中包含Elsie内容
print(soup.find_all(text='Elsie'))

也可以与其他参数混合使用来过滤tag

#获取文本中包含Elsie内容的标签
print(soup.find_all('a',text='Elsie'))
6.1.6 limit参数
6.1.6.1 作用

用于限制返回结果的数量

6.1.6.2 参数形式

整数

#获取前两个a标签
print(soup.find_all('a',limit=2))
6.1.7 recursive参数
6.1.7.1 作用

决定是否获取子孙节点

6.1.7.2 参数形式

布尔值,默认是True

print(soup.find_all('title',recursive=False))
6.1.8 样例

name参数用来接收tag名称,有四种形式:字符串,正则。列表和True
attrs参数用来接收属性的键值对字典
kwargs参数用来接收常用属性的变量赋值的形式 例如:id = ‘link1’, class_ = “sister”
text参数用来接收文本信息
limit参数用来限制返回结果的数量
recursive参数用来决定是否获取子孙节点

html = '''
<div class="panel">
     <div class="panel-heading">
        <h4>Hello</h4>
     </div>
     <div class="panel-body">
          <ul class="list" id="list-1">
               <li class="element">
               <span>Foo</span>
               </li>
               <li class="element">Bar</li>
               <li class="element">Jay</li>
          </ul>
          <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
          </ul>
     </div>
</div>
'''


#1、导入Beautiful Soup类
from bs4 import BeautifulSoup

#2、传入参数,实例化这个类
soup = BeautifulSoup(html)

#3、使用attrs获取id为link1的标签
print(soup.find_all(attrs={'id':'link1'}))

#4、使用kwargs获取class等于sister的标签
print(soup.find_all(class='sister'))

#5、使用text获取包含story的标签
import re
print(soup.find_all(name='b',text=re.compile('.*?story')))

#6、使用limit限制p标签的查询只获取第一个
print(soup.find_all(name='p',limit=1))

#7、使用recursive限制第一个p标签的查询
print(soup.find_all('p',limit=1,recursive=False))

6.2 find()方法

6.2.1 作用

find( ) 方法和find_all( ) 方法类似,都是在文档中查找所需要的信息

6.2.2 区别

find_all( ) 方法返回所有符合条件的元素列表(查找当前节点下,符合条件的所有节点)
find( ) 方法就是返回符合条件的第一个元素(查找当前节点下,符合条件的第一个节点)

6.2.3 可供使用参数

name, attrs, text, kwargs, recursive (没有limit参数)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊凯瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值