首頁  >  文章  >  後端開發  >  Python之BeautifulSoup庫安裝及其簡介

Python之BeautifulSoup庫安裝及其簡介

高洛峰
高洛峰原創
2017-03-11 09:49:022997瀏覽

一. 前言

        在前面的幾篇文章中我介紹如何透過Python分析原始碼爬取部落格、維基百科InfoBox和圖片,文章連結如下:
        [python學習] 簡單爬取維基百科程式語言訊息盒
        [Python學習] 簡單網路爬蟲抓取部落格文章及想法介紹
        [python學習] 簡單爬取圖片網站圖片庫圖片
        其中核心程式碼如下:

# coding=utf-8
import urllib
import re

#下载静态HTML网页
url='http://www.csdn.net/'
content = urllib.urlopen(url).read()
open('csdn.html','w+').write(content)
#获取标题
title_pat=r&#39;(?<=<title>).*?(?=</title>)&#39;
title_ex=re.compile(title_pat,re.M|re.S)
title_obj=re.search(title_ex, content)
title=title_obj.group()
print title
#获取超链接内容 
href = r&#39;<a href=.*?>(.*?)</a>&#39;
m = re.findall(href,content,re.S|re.M)
for text in m:
    print unicode(text,&#39;utf-8&#39;)
    break #只输出一个url

       

>>>
CSDN.NET - 全球最大中文IT社区,为IT专业技术人员提供最全面的信息传播和服务平台
登录
>>>

##       
輸出結果如下:

import os
import urllib
class AppURLopener(urllib.FancyURLopener):
    version = "Mozilla/5.0"
urllib._urlopener = AppURLopener()
url = "http://creatim.allyes.com.cn/imedia/csdn/20150228/15_41_49_5B9C9E6A.jpg"
filename = os.path.basename(url)
urllib.urlretrieve(url , filename)

#        圖片下載的核心程式碼如下:

#

#!/usr/bin/python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup

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

#获取BeautifulSoup对象并按标准缩进格式输出
soup = BeautifulSoup(html_doc)
print(soup.prettify())



        但是上面這種分析HTML來爬取網站內容的方法存在很多弊端,譬如:
        1.正則表達式被HTML源碼所約束,而不是取決於更抽象的結構;網頁結構中很小的改動可能會導致程式的中斷。
        2.程式需要根據實際HTML原始碼分析內容,可能會遇到字元實體如&之類的HTML特性,需要指定處理如45a2772a6b6107b401db3c9b82c049c254bdf357c58b8a65c66d7c19c8e4d114、圖示超連結、下標等不同內容。         3.正規表示式並不是完全可讀的,更複雜的HTML程式碼和查詢表達式會變得很亂。         正如《Python基礎教學(第2版)》採用兩種解決方案:第一個是使用Tidy(Python庫)的程式和XHTML解析;第二個是使用BeautifulSoup函式庫。



二. 安裝與介紹Beautiful Soup函式庫

       
Beautiful Soup是用Python寫的一個HTML/XML的解析器,它可以很好的處理不規範標記並產生剖析樹(parse tree)。 它提供簡單又常用的導航navigating,搜尋以及修改剖析樹的操作。它可以大大節省你的程式時間。
      正如書中所說「那些糟糕的網頁不是你寫的,你只是試圖從中獲得一些資料。現在你不用關心HTML是什麼樣子的,解析器幫你實現」。       
#下載網址:
##        http://www#        

http://www .php.cn/

        http://www.php.cn/

       

安裝流程如下圖所示:python setup.py install



##        特定使用方法建議參考中文:
        http://www.php.cn/

        其中BeautifulSoup的用法簡單講解下,使用「愛麗絲夢遊仙境」的官方範例:


#

<html>
 <head>
  <title>
   The Dormouse&#39;s story
  </title>
 </head>
 <body>
  <p class="title">
   <b>
    The Dormouse&#39;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://example.com/elsie" id="link1">
    Elsie
   </a>
   ,
   <a class="sister" href="http://example.com/lacie" id="link2">
    Lacie
   </a>
   and
   <a class="sister" href="http://example.com/tillie" id="link3">
    Tillie
   </a>
   ;
and they lived at the bottom of a well.
  </p>
  <p class="story">
   ...
  </p>
 </body>
</html>

######       ########## 依照標準的縮排格式的結構輸出###如下: ############
&#39;&#39;&#39;获取title值&#39;&#39;&#39;
print soup.title
# <title>The Dormouse&#39;s story</title>
print soup.title.name
# title
print unicode(soup.title.string)
# The Dormouse&#39;s story

&#39;&#39;&#39;获取<p>值&#39;&#39;&#39;
print soup.p
# <p class="title"><b>The Dormouse&#39;s story</b></p>
print soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

&#39;&#39;&#39;从文档中找到<a>的所有标签链接&#39;&#39;&#39;
print soup.find_all(&#39;a&#39;)
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
for link in soup.find_all(&#39;a&#39;):
    print(link.get(&#39;href&#39;))
    # http://www.php.cn/
    # http://www.php.cn/
    # http://www.php.cn/
print soup.find(id=&#39;link3&#39;)
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
#########        以下是BeautifulSoup庫簡單快速入門介紹:(參考:官方文件)############
&#39;&#39;&#39;从文档中获取所有文字内容&#39;&#39;&#39;
print soup.get_text()
# The Dormouse&#39;s story
#
# The Dormouse&#39;s story
#
# Once upon a time there were three little sisters; and their names were
# Elsie,
# Lacie and
# Tillie;
# and they lived at the bottom of a well.
#
# ...
#########        若想要取得文章中所有文字內容,程式碼如下:############
&#39;&#39;&#39;从文档中获取所有文字内容&#39;&#39;&#39;
print soup.get_text()
# The Dormouse&#39;s story
#
# The Dormouse&#39;s story
#
# Once upon a time there were three little sisters; and their names were
# Elsie,
# Lacie and
# Tillie;
# and they lived at the bottom of a well.
#
# ...

        同时在这过程中你可能会遇到两个典型的错误提示:
        1.ImportError: No module named BeautifulSoup
        当你成功安装BeautifulSoup 4库后,“from BeautifulSoup import BeautifulSoup”可能会遇到该错误。


        其中的原因是BeautifulSoup 4库改名为bs4,需要使用“from bs4 import BeautifulSoup”导入。
        2.TypeError: an integer is required
        当你使用“print soup.title.string”获取title的值时,可能会遇到该错误。如下:


        它应该是IDLE的BUG,当使用命令行Command没有任何错误。参考:stackoverflow。同时可以通过下面的代码解决该问题:
        print unicode(soup.title.string)
        print str(soup.title.string)


三. Beautiful Soup常用方法介绍


       
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:Tag、NavigableString、BeautifulSoup、Comment|
        1.Tag标签
        tag对象与XML或HTML文档中的tag相同,它有很多方法和属性。其中最重要的属性name和attribute。用法如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup

html = """
<html><head><title>The Dormouse&#39;s story</title></head>
<body>
<p class="title" id="start"><b>The Dormouse&#39;s story</b></p>
"""
soup = BeautifulSoup(html)
tag = soup.p
print tag
# <p class="title" id="start"><b>The Dormouse&#39;s story</b></p>
print type(tag)
# <class &#39;bs4.element.Tag&#39;>
print tag.name
# p 标签名字
print tag[&#39;class&#39;]
# [u&#39;title&#39;]
print tag.attrs
# {u&#39;class&#39;: [u&#39;title&#39;], u&#39;id&#39;: u&#39;start&#39;}

        使用BeautifulSoup每个tag都有自己的名字,可以通过.name来获取;同样一个tag可能有很多个属性,属性的操作方法与字典相同,可以直接通过“.attrs”获取属性。至于修改、删除操作请参考文档。
        2.NavigableString
        字符串常被包含在tag内,Beautiful Soup用NavigableString类来包装tag中的字符串。一个NavigableString字符串与Python中的Unicode字符串相同,并且还支持包含在遍历文档树搜索文档树中的一些特性,通过unicode()方法可以直接将NavigableString对象转换成Unicode字符串。

print unicode(tag.string)
# The Dormouse&#39;s story
print type(tag.string)
# <class &#39;bs4.element.NavigableString&#39;>
tag.string.replace_with("No longer bold")
print tag
# <p class="title" id="start"><b>No longer bold</b></p>

        这是获取“6924be786dcb0892a956090fd509f9a5a4b561c25d9afb9ac8dc4d70affff419The Dormouse's story0d36329ec37a2cc24d42c7229b69747a94b3e26ee717c64999d7867364b1b4a3”中tag = soup.p的值,其中tag中包含的字符串不能编辑,但可通过函数replace_with()替换。
        NavigableString 对象支持遍历文档树和搜索文档树 中定义的大部分属性, 并非全部。尤其是一个字符串不能包含其它内容(tag能够包含字符串或是其它tag),字符串不支持 .contents 或 .string 属性或 find() 方法。
        如果想在Beautiful Soup之外使用 NavigableString 对象,需要调用 unicode() 方法,将该对象转换成普通的Unicode字符串,否则就算Beautiful Soup已方法已经执行结束,该对象的输出也会带有对象的引用地址。这样会浪费内存。

        3.Beautiful Soup对象
        该对象表示的是一个文档的全部内容,大部分时候可以把它当做Tag对象,它支持遍历文档树和搜索文档树中的大部分方法。
        注意:因为BeautifulSoup对象并不是真正的HTML或XML的tag,所以它没有name和 attribute属性,但有时查看它的.name属性可以通过BeautifulSoup对象包含的一个值为[document]的特殊实行.name实现——soup.name。
        Beautiful Soup中定义的其它类型都可能会出现在XML的文档中:CData , ProcessingInstruction , Declaration , Doctype 。与 Comment 对象类似,这些类都是 NavigableString 的子类,只是添加了一些额外的方法的字符串独享。
        4.Command注释
        Tag、NavigableString、BeautifulSoup几乎覆盖了html和xml中的所有内容,但是还有些特殊对象容易让人担心——注释。Comment对象是一个特殊类型的NavigableString对象。

markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
print type(comment)
# <class &#39;bs4.element.Comment&#39;>
print unicode(comment)
# Hey, buddy. Want to buy a used parser?

        介绍完这四个对象后,下面简单介绍遍历文档树和搜索文档树及常用的函数。
        5.遍历文档树
        一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点。BeautifulSoup提供了许多操作和遍历子节点的属性。引用官方文档中爱丽丝例子:
        操作文档最简单的方法是告诉你想获取tag的name,如下:

soup.head# 93f0f5c25f18dab9d176bd4f6de5d30eb2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f9c3bca370b5104690d9ef395f2c5f8d1soup.title# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2fsoup.body.b# a4b561c25d9afb9ac8dc4d70affff419The Dormouse's story0d36329ec37a2cc24d42c7229b69747a

        注意:通过点取属性的放是只能获得当前名字的第一个Tag,同时可以在文档树的tag中多次调用该方法如soup.body.b获取6c04bd5ca3fcae76e30b72ad730ca86d标签中第一个a4b561c25d9afb9ac8dc4d70affff419标签。
        如果想得到所有的3499910bf9dac5ae3c52d5ede7383485标签,使用方法find_all(),在前面的Python爬取维基百科等HTML中我们经常用到它+正则表达式的方法。

soup.find_all('a')# [31602ad08f2e88060105421a6fd98432Elsie5db79b134e9f6b82c0b36e0489ee08ed,#  7a2353bc01007f1e0b12a80523342380Lacie5db79b134e9f6b82c0b36e0489ee08ed,#  de05147b7e6ab3a313271cf7987ced2eTillie5db79b134e9f6b82c0b36e0489ee08ed]

        子节点:在分析HTML过程中通常需要分析tag的子节点,而tag的 .contents 属性可以将tag的子节点以列表的方式输出。字符串没有.contents属性,因为字符串没有子节点。

head_tag = soup.head
head_tag
# 93f0f5c25f18dab9d176bd4f6de5d30eb2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f9c3bca370b5104690d9ef395f2c5f8d1

head_tag.contents
[b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f]

title_tag = head_tag.contents[0]
title_tag
# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f
title_tag.contents
# [u'The Dormouse's story']

        通过tag的 .children 生成器,可以对tag的子节点进行循环:

for child in title_tag.children:
    print(child)
    # The Dormouse's story

        子孙节点:同样 .descendants 属性可以对所有tag的子孙节点进行递归循环:

for child in head_tag.descendants:
    print(child)
    # b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f
    # The Dormouse's story

        父节点:通过 .parent 属性来获取某个元素的父节点.在例子“爱丽丝”的文档中,93f0f5c25f18dab9d176bd4f6de5d30e标签是b2386ffb911b14667cb8f0f91ea547a7标签的父节点,换句话就是增加一层标签。
        注意:文档的顶层节点比如100db36a723c770d327fc0aef2ce13b1的父节点是 BeautifulSoup 对象,BeautifulSoup 对象的 .parent 是None。

title_tag = soup.titletitle_tag# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2ftitle_tag.parent# 93f0f5c25f18dab9d176bd4f6de5d30eb2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f9c3bca370b5104690d9ef395f2c5f8d1title_tag.string.parent# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f

        兄弟节点:因为a4b561c25d9afb9ac8dc4d70affff419标签和f8331b8a817c28418a431fbe6e724755标签是同一层:他们是同一个元素的子节点,所以a4b561c25d9afb9ac8dc4d70affff419和f8331b8a817c28418a431fbe6e724755可以被称为兄弟节点。一段文档以标准格式输出时,兄弟节点有相同的缩进级别.在代码中也可以使用这种关系。

sibling_soup = BeautifulSoup("3499910bf9dac5ae3c52d5ede7383485a4b561c25d9afb9ac8dc4d70affff419text10d36329ec37a2cc24d42c7229b69747af8331b8a817c28418a431fbe6e724755text29058c75f7b5bb1e6daacddf9bb18d9590d36329ec37a2cc24d42c7229b69747a5db79b134e9f6b82c0b36e0489ee08ed")print(sibling_soup.prettify())# 100db36a723c770d327fc0aef2ce13b1#  6c04bd5ca3fcae76e30b72ad730ca86d#   3499910bf9dac5ae3c52d5ede7383485#    a4b561c25d9afb9ac8dc4d70affff419#     text1#    0d36329ec37a2cc24d42c7229b69747a#    f8331b8a817c28418a431fbe6e724755#     text2#    9058c75f7b5bb1e6daacddf9bb18d959#   5db79b134e9f6b82c0b36e0489ee08ed#  36cc49f0c466276486e50c850b7e4956# 73a6ac4ed44ffec12cee46588e518a5e

        在文档树中,使用 .next_sibling 和 .previous_sibling 属性来查询兄弟节点。a4b561c25d9afb9ac8dc4d70affff419标签有.next_sibling 属性,但是没有.previous_sibling 属性,因为a4b561c25d9afb9ac8dc4d70affff419标签在同级节点中是第一个。同理f8331b8a817c28418a431fbe6e724755标签有.previous_sibling 属性,却没有.next_sibling 属性:

sibling_soup.b.next_sibling# f8331b8a817c28418a431fbe6e724755text29058c75f7b5bb1e6daacddf9bb18d959sibling_soup.c.previous_sibling# a4b561c25d9afb9ac8dc4d70affff419text10d36329ec37a2cc24d42c7229b69747a

        介绍到这里基本就可以实现我们的BeautifulSoup库爬取网页内容,而网页修改、删除等内容建议大家阅读文档。下一篇文章就再次爬取维基百科的程序语言的内容吧!希望文章对大家有所帮助,如果有错误或不足之处,还请海涵!建议大家阅读官方文档和《Python基础教程》书。
        (By:Eastmount 2015-3-25 下午6点  http://www.php.cn/)



以上是Python之BeautifulSoup庫安裝及其簡介的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn