BeautifulSoup的用法案例简介
在《Python爬虫利器-XPath》文中,我们介绍了XPath,使用它来进行页面文本信息提取方便快捷。在本文中,小编将介绍另外一个好用的工具–BeautifulSoup,使用它同样可以实现快速提取页面文本信息。
1.什么是BeautifulSoup
BeautifulSoup是一个从HTML或者XML文件中利用标签树功能快速提取数据的Python库。它用法简单,通过转换器把文档解析成文档树,实现查找、修改指定内容的功能。使用它,短短几行命令,就可以满足我们的大多数需求。引用方式是: from bs4 import BeautifulSoup或者import bs4。
2.用法示例
我们使用和上一篇推文中相似的HTML:
<bookstore>
<book category="Fantasy Novels">
<a href="http://blog.csdn.net/qq_36148847">链接</a>
<title lang="English">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="武侠小说">
<title lang="中文">天龙八部</title>
<author>金庸</author>
<year>2005</year>
<price>40</price>
</book>
</bookstore>
此处的HTML经解析之后,对应的子节点、父节点、兄弟节点的定义和之前推文中介绍的相同,不再赘述。
3.程序详解
3.1简单入门
我们导入指定模块,并输入该HTML:
In[1]:from bs4 import BeautifulSoup
In[2]:html ='''<bookstore><book category="Fantasy Novels"><a href="http://blog.csdn.net/qq_36148847">链接</a><title lang="English">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="武侠小说"><title lang="中文">天龙八部</title><author>金庸</author><year>2005</year><price>40</price></book></bookstore>'''
In[3]:soup=BeautifulSoup(html,'xml') #将输入的html文本转换成BeautifulSoup对象
In[4]:print(type(soup))
Out[4]: <class 'bs4.BeautifulSoup'>
In[5]:print(soup)
Out[5]: <?xml version="1.0" encoding="utf-8"?>
<bookstore><book category="Fantasy Novels"><a href="http://blog.csdn.net/qq_36148847">链接</a><title lang="English">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="武侠小说"><title lang="中文">天龙八部</title><author>金庸</author><year>2005</year><price>40</price></book></bookstore>
可见,解析之后的文本类型是一个bs对象。该对象相比最初的文本内容,在开头声明了xml版本以及编码类型是utf8编码,但是此时文本内容依然按原样罗列了出来,并不清晰,我们使用以下这个方法可以得到自动缩进对齐的格式。
In[6]:print(soup.prettify())
Out[6]:<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="Fantasy Novels">
<a href="http://blog.csdn.net/qq_36148847">
链接
</a>
<title lang="English">
Harry Potter
</title>
<author>
J K. Rowling
</author>
<year>
2005
</year>
<price>
29.99
</price>
</book>
<book category="武侠小说">
<title lang="中文">
天龙八部
</title>
<author>
金庸
</author>
<year>
2005
</year>
<price>
40
</price>
</book>
</bookstore>
所以当我们不清楚当前文本内容的节点相对关系,就可以使用上述方法将其美化并打印出来。这样一来,清晰明了,赏心悦目。
我们以第一个title为例,进行解析:
In[7]:print(soup.title)
Out[7]:<title lang="English">Harry Potter</title>
In[8]:print(soup.title.name)
Out[8]:title
In[9]:print(soup.title.string)
Out[9]:Harry Potter
In[10]:print(soup.title["lang"])
Out[10]:English
可以看出,第一个title节点,它的name是title,string是对应的文本内容即Harry Potter,lang属性是English。
3.2使用不同方法提取第一个title的内容
(1)在soup下,调取第一个title节点(此处应当注意,文本中有两个title,使用“.”调取的是默认调取第一个),然后使用.string调取它的文本内容。
In[7]:print(soup.title.string)
(2)在soup下,调取第一个title节点,然后使用get_text()方法调取文本内容。
In[8]:print(soup.title.get_text())
(3)在soup下,调取第一个author节点,然后使用.previous_sibling调取上一个兄弟节点,再取其文本内容。
In[9]:print(soup.author.previous_sibling.string)
(4)在soup下,调取第一个a节点,然后使用.next_sibling调取下一个兄弟节点,再取其文本内容。
In[10]:print(soup.a.next_sibling.string)
(5)使用find方法(注:find方法默认调取第一个节点)。
In[11]:title1=soup.find("title")
In[12]:print(title1.string)
(6)使用find_all方法(注:find_all方法调取全文所有目标节点)。
In[13]:title2=soup.find_all("title",lang="English") #寻找所有title节点,而且它的lang属性为English
In[14]:for unittitle in title2:
In[15]: print(unittitle.string)
(7)使用find_all方法:我们也可以不声明节点是什么,而只声明某一属性。
In[16]:title3=soup.find_all(lang="English") #寻找所有lang属性为English的节点
In[17]:for unittitle in title3:
In[18]: print(unittitle.string)
以上各种方法得到的结果如下:
4.小结
以上是我们使用BeautifulSoup的惯用手法,它使用文档树这一工具配合简单的语法,轻松实现我们提取目标信息的要求。小伙伴们可以mark起来,用它来处理网页源代码吧。