Python公开课 - 页面解析之Beautiful Soup

前言

python beautiful soup

Beautiful Soup提供一些简单的、Python式的函数来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

同时可以自动将输入文档转换为Unicode编码,输出文档转换为UTF-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时你仅仅需要说明一下原始编码方式就可以了。

所以说,利用Beautiful Soup可以省去很多烦琐的提取工作,提高解析效率。

Beautiful Soup基本使用

我们先看一个例子:

from bs4 import BeautifulSoup

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

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://www.xtuz.net/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://www.xtuz.net/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://www.xtuz.net/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')
print(soup.prettify())
print(soup.title.string)

输出:
<html>
 <head>
  <title>
   The Dormouse's story
  </title>
 </head>
 <body>
  <p class="title">
   <b>
    The Dormouse's story
   </b>
  </p>
  <p class="story">
   Once upon a time there were three little sisters; and their names were
   <a class="sister" href="http://www.xtuz.net/elsie" id="link1">
    Elsie
   </a>
   ,
   <a class="sister" href="http://www.xtuz.net/lacie" id="link2">
    Lacie
   </a>
   and
   <a class="sister" href="http://www.xtuz.net/tillie" id="link3">
    Tillie
   </a>
   ;
and they lived at the bottom of a well.
  </p>
  <p class="story">
   ...
  </p>
 </body>
</html>

这里调用prettify()方法,可以把要解析的字符串以标准的缩进格式输出,然后调用soup.title.string,用来输出HTML中title节点的文本内容。

查找

直接选择元素

print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)

输出:
<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story
<head><title>The Dormouse's story</title></head>
<p class="title"><b>The Dormouse's story</b></p>

首先打印输出title节点的选择结果,输出结果正是title节 点加里面的文字内容。

接下来,输出它的类型,是bs4.element.Tag类型,这是Beautiful Soup中一个重要的数据结构。经过选择器选择后,选择结果都是这种 Tag 类型。Tag 具有一些属性,比如string属性,调用该属性,可以得到节点的文本内容,所以接下来的输出结果正是节点的文本内容。

我们选择了head节点,结果也是节点加其内部的所有内容。

最后,选择了p节点,不过这次情况比较特殊,我们发现结果是第一个p节点的内容,后面的几个p节点并没有选到,也就是说,当有多个节点时,这种选择方式只会选择到第一个匹配的节点,其他的后面节点都会忽略。

find_all() - 查询符合条件的元素

通过给该方法传入一些属性或文本,就可以得到符合条件的元素,它的功能十分强大。

  • 根据节点名来查找
print(soup.find_all(name='p'))
print(type(soup.find_all(name='p')[0]))

输出:
[<p class="title"><b>The Dormouse's story</b></p>, <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://www.xtuz.net/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://www.xtuz.net/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://www.xtuz.net/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="story">...</p>]
<class 'bs4.element.Tag'>
  • 根据属性来查找
print(soup.find_all(attrs={'class':'story'}))

输出:
[<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://www.xtuz.net/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://www.xtuz.net/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://www.xtuz.net/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="story">...</p>]
  • 根据文本来查找
import re
print(soup.find_all(text=re.compile('Lacie')))

输出:
['Lacie']

find() - 查询首个符合条件的元素

find()方法,返回的是单个元素,也就是第一个匹配的元素, 使用同上述一样,不做更多说明。

select() - CSS选择查找

在Tag或BeautifulSoup对象的select() 方法中传入字符串参数,即可使用CSS选择器的语法找到Tag。

print(soup.select('.story'))

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

可以看到用select()函数,也非常方便。

数据提取

提取名称

可以利用name属性获取节点的名称。选取title节点,然后调用name属性就可以得到节点名称:

print(soup.title.name) 

输出:
title

提取属性

每个节点可能有多个属性,比如id和class等,选择这个节点元素后,可以调用attrs获取所有属性:

print(soup.p.attrs)
print(soup.p.attrs['class'])

输出:
{'class': ['title']}
['title']

其中attrs的返回结果是字典形式,它把选择的节点的所有属性和属性值组合成一个字典。

这里需要注意的是,有的返回结果是字符串,有的返回结果是字符串组成的列表,在实际情况中,我们需要根据不同的返回类型做出正确的响应处理。

提取文本内容

可以利用string 属性获取节点元素包含的文本内容,比如要获取第一个p节点的文本

print(soup.p.string) 

输出:
The Dormouse's story

小结

Beautiful Soup作为用Python写的一个HTML/XML的解析器,它可以很好的处理不规范的标记,并提供简单又常用的搜索,抽取功能,大大节省你的编程时间。

相关阅读


相关推荐
  1. 多多益善
  2. 脱单!武汉的相亲角在哪你知道吗?
  3. Python公开课 - Django自动添加Last-Modified和ETag
  4. 华东理工大学附属中学(高中部)
  5. 面试宝典
  6. 陵城镇南庄小学
  7. 吉林省长春市宽城区明星双语幼儿园 - 长春幼儿园黄页
  8. 欧洲来客马可·波罗
  9. 江门市崖门镇仙洞学校(小学部)
  10. 上海市静安恒丰中学
  11. 狐狸的大尾巴掉了
  12. 警方通报:武汉男子持刀至五死一伤,嫌犯已跳桥
  13. 上海市张泽学校(初中部)
  14. 北京市崇文(东城)区西草市幼儿园 - 北京幼儿园黄页
  15. 沈阳市辽中县育佳幼儿园 - 沈阳幼儿园黄页
  16. python中带b字符串转换
  17. 武汉推出越王勾践剑交通卡
  18. 柳州市鹿寨县春光幼儿园 - 柳州市幼儿园黄页
  19. 北京市石景山区金阶梯教育玉泉路校区 - 北京幼儿园黄页
  20. 天心区大托镇兴隆小学
  21. 聪明的村姑
  22. 南宁市西乡塘区育宝玉堂幼儿园 - 南宁幼儿园黄页
  23. Python公开课 - 解释器详解
  24. 呼兰区康金镇徐加野小学校
  25. 佛山高明区人和中学(现杨和中学)
  26. 阜阳实验小学
  27. 详解Tesseract之安装及基本使用
  28. 佛山市西南街道第十一小学(西南十一小)
  29. 保定市同济中学
  30. 少年孙武的传说
  31. 事发武汉农夫山泉矿泉水内惊现大量虫卵
  32. 徐闻县职业高级中学
  33. Python公开课 - 爬虫之HTTP基础
  34. 湖北将发放消费券 - 武汉新鲜事
  35. 奥迪客户不满加价,被武汉4S店销售群殴
  36. 幼儿园入学准备物品清单
  37. Python的起源 - 二十年前的故事
  38. 上海市宝山区陈行新村幼儿园 - 上海幼儿园黄页
  39. 韶关市武江区金福园小学
  40. 小猴的出租车
  41. 安如泰山
  42. 易中天给英雄武汉的一首诗 - 武汉新鲜事
  43. 湛江市第九小学
  44. 洼兴镇中心幼儿园 - 哈尔滨幼儿园黄页
  45. 鹤壁市第一中学(鹤壁一中)
  46. 武汉女子网上做兼职被骗六十五万
  47. 西安市未央区 爱儿坊华远君城社区幼儿园 - 西安幼儿园黄页
  48. 红牙齿阿英
  49. 星月幼儿园 - 成都市幼儿园黄页
  50. 笑笑和他的欢乐袋
  51. Python源码剖析 - Python中的字符串对象
  52. 邳州市铁富高级中学
  53. 央媒聚焦!国庆假期173.78万人次打卡大美黄陂
  54. 爱迟到的小鱼莎莎
  55. 北京市东城区黑芝麻胡同小学
  56. 西安市十二中学
  57. 安徽省铜陵市第十一中学
  58. Python公开课 - 爬虫识别滑动验证码
  59. 武汉动物园火烈鸟孔雀排队打疫苗
  60. Python Selenium find_element_by_css_selector 如何处理多个class
  61. 广州市越秀区大沙头小学