使用Beautiful Soup解析库

使用Beautiful Soup解析库

简介

支持的解析器

基本用法

html ="""
<html id="html" manifest="offlintab.appcache">
  <meta charset="utf-8">
  <title>新标签页</title>
  <base>
  <link type="text/css" rel="stylesheet" href="/static/css/offlintab-468.css">
  <script type="application/javascript" src="/static/js/offlintab-468.js"></script>
  <body id="body">
  """
  
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml') 
print(soup.prettify())  #把要解析的字符串以标准的缩进格式输出
print(soup.title.string) #输出HTML中title节点的文本内容
#soup.title可以选出HTML中的title节点,再调用string属性就可以得到里面的文本

节点选择器

说明:直接调用节点的名称就可以选择节点元素,再调用string属性就可以得到节点内的文本了,这种选择方式速度非常快。如果单个节点结构层次非常清晰,可以选用这种方式来解析。

提取信息

说明:包括选择元素、获取内容、获取名称、获取属性简单用法

代码说明:

html ="""
 <a id="export-to" download="exported.json" hidden="true">
    <title>新标签页</title>
    <a id="setdefault" hidden="true">设为默认浏览器</a>
    <p id="promo" hidden="true">
      <button title="关闭"></button>
    </a>
    <nav id="navpane">
      <a id="fx-accounts" hidden="true"></a>
      <a data-pane="nav" title="切换至导航页">Nav</a>
      <a data-pane="blank" title="切换至空白页">Blank</a>
    </nav>
    <footer id="footer">
      <a href="" title="火狐主页">
        <img src="/static/img/Logo-quantum.png" alt="Firefox" />
      </a>
  """
  
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print()
print(soup.title)  #选择元素
print(soup.title.string)  #获取节点内的文本
print(soup.title.name) #获取节点名称
print(soup.p.attrs)  #每个节点可能有多个属性,调用attrs获取所有属性 
                      或者 直接使用soup.p['id']

运行结果:

============================= RESTART: F:/bs.py =============================
<html id="html" manifest="offlintab.appcache">
 <head>
  <meta charset="utf-8"/>
  <title>
   新标签页
  </title>
  <base/>
  <link href="/static/css/offlintab-468.css" rel="stylesheet" type="text/css"/>
  <script src="/static/js/offlintab-468.js" type="application/javascript">
  </script>
 </head>
 <body id="body">
 </body>
</html>
新标签页

<title>新标签页</title>
新标签页
title
{'id': 'promo', 'hidden': 'true'}

嵌套选择

说明:上面每一个例子的返回结果都是bs4.element.Tag类型,它同样可以继续调用节点进行操作。

代码说明:

#嵌套选择
html ="""
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <link rel="canonical" href="https://blog.csdn.net/hefenglian/article/details/83450938"/>
    <title>Redis数据库介绍(1) - 洞玄之境的博客 - CSDN博客</title>
                    <link rel="stylesheet" href="https://csdnimg.cn/css/b9b02f.min.css">
    </style>
</head>
  """
  
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print()
print(type(soup.head))
print(soup.head.title)
print(soup.head.title.string)  #获取节点内的文本


运行结果
============================= RESTART: F:/bs.py =============================

<class 'bs4.element.Tag'>  
<title>Redis数据库介绍(1) - 洞玄之境的博客 - CSDN博客</title>
Redis数据库介绍(1) - 洞玄之境的博客 - CSDN博客

关联选择

说明:在做选择的时候,有时候不能做到一步就选到想要的节点元素,需要先选中某一个节点元素,然后以它为基准再选择它的子节点,父节点,兄弟节点等,以下介绍如何选择这些节点元素。

子节点和子孙节点

说明:要得到所有的子节点,可以调用contents属性 或者 调用children属性;
要得到所有的子孙节点的话,可以调用descendants属性。

代码说明:

#关联选择
html ="""
 <a id="export-to" download="exported.json" hidden="true">
    <title>新标签页</title>
    <a id="setdefault" hidden="true">设为默认浏览器</a>
    <p id="promo" hidden="true">
      <button title="关闭"></button>
    </a>
    <nav id="navpane">
      <a id="fx-accounts" hidden="true"></a>
      <a data-pane="nav" title="切换至导航页">Nav</a>
      <a data-pane="blank" title="切换至空白页">Blank</a>
      <span>Elise</span>
    </nav></p>
    <footer id="footer">
      <a href="" title="火狐主页">
        <img src="/static/img/Logo-quantum.png" alt="Firefox" />
      </a>
  """
  
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print()
print(soup.p.contents)  #返回一个列表
print()
print(soup.p.children)  #返回结果是生成器类型,要用for循环输出

for i,child in enumerate(soup.p.children):
    print(i,child)
for i,child in enumerate(soup.p.descendants):    #返回结果是生成器类型
	print(i,child)
 #这两行可以写成print(list(enumerate(soup.p.descendants)))直接变为list

父节点和祖先节点

说明:
如果要获取某个节点元素的父节点,可以调用parent属性;
如果要获取某个节点元素的祖先节点,可以调用parents属性。

兄弟节点

  
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')

print('Next Sibling',soup.a.next_sibling)   #节点的下一个元素
print('Prev Sibling',soup.a.previous_sibling)

print('Next Sibling',list(enumerate(soup.a.next_sibling))) 
 #返回所有后面节点的生成器,然后用list转一下
print('Prev Sibling',list(enumerate(soup.a.previous_sibling)))


小结

关联元素里面的都可以用提取信息说的方法。

查询方法

说明:前面所讲的选择方法都是通过属性来选择的,这种方法非常快,但是如果进行比较复杂的选择的话,它就比较繁琐,不够灵活了。幸好,Beautiful Soup 还为我们提供了一些查询方法,比如find_all()、find()等,调用他们,然后传入相应的参数就可灵活运用了。

find_all()

说明:find_all, 顾名思义,就是查询所有符合条件的元素。给它传入一些属性或文本,就可以得到符合条件的元素,它的功能十分强大。
它的API如下:find_all(name, attrs, recursive, text, **kwargs)
代码说明下name, attrs,text:

import re
from bs4 import BeautifulSoup	
#调用lxml解析器
soup = BeautifulSoup(html,"lxml")
print(soup.find_all(name='a'))  #根据节点名来查询元素,返回结果是列表类型,每个元素依然是bs4.element.Tag类型。
print()
print(soup.find_all(attrs={'id': 'export-to'}))  #传入一些属性来查询 或者 使用另一个方式print(soup.find_all(id='export-to'))
print()
print(soup.find_all(text = re.compile('a')))  #text参数用来匹配节点的文本,传入的形式可以是字符串,可以是正则表达式对象

find()

说明:除了find_all()方法,还有find()方法,只不过后者返回的是单个元素,也就是第一个匹配的元素,而前者返回的是所有匹配的元素组成的列表。

CSS选择器

CSS选择器参考手册
使用CSS选择器时,只需要调用select()方法,传入相应的CSS选择器即可,如

from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')

print(soup.select('a p'))    # 选择 <a> 元素内部的所有 <p> 元素   
发布了43 篇原创文章 · 获赞 46 · 访问量 4506

猜你喜欢

转载自blog.csdn.net/S_123789/article/details/101113163