[python知识] 爬虫知识之BeautifulSoup库安装及简单介绍
生活随笔
收集整理的這篇文章主要介紹了
[python知识] 爬虫知识之BeautifulSoup库安装及简单介绍
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一. 前言
? ? ? ? 在前面的幾篇文章中我介紹了如何通過Python分析源代碼來爬取博客、維基百科InfoBox和圖片,其文章鏈接如下:
? ? ? ? [python學習] 簡單爬取維基百科程序語言消息盒
? ? ? ??[Python學習] 簡單網絡爬蟲抓取博客文章及思想介紹
? ? ? ? [python學習] 簡單爬取圖片網站圖庫中圖片
? ? ? ? 其中核心代碼如下:
>>> 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) ? ? ? ? 但是上面這種分析HTML來爬取網站內容的方法存在很多弊端,譬如:
? ? ? ? 1.正則表達式被HTML源碼所約束,而不是取決于更抽象的結構;網頁結構中很小的改動可能會導致程序的中斷。
? ? ? ? 2.程序需要根據實際HTML源碼分析內容,可能會遇到字符實體如&之類的HTML特性,需要指定處理如<span></span>、圖標超鏈接、下標等不同內容。
? ? ? ? 3.正則表達式并不是完全可讀的,更復雜的HTML代碼和查詢表達式會變得很亂。
? ? ? ? 正如《Python基礎教程(第2版)》采用兩種解決方案:第一個是使用Tidy(Python庫)的程序和XHTML解析;第二個是使用BeautifulSoup庫。
二. 安裝及介紹Beautiful Soup庫
? ? ? ?Beautiful Soup是用Python寫的一個HTML/XML的解析器,它可以很好的處理不規范標記并生成剖析樹(parse tree)。 它提供簡單又常用的導航navigating,搜索以及修改剖析樹的操作。它可以大大節省你的編程時間。
? ? ? 正如書中所說“那些糟糕的網頁不是你寫的,你只是試圖從中獲得一些數據。現在你不用關心HTML是什么樣子的,解析器幫你實現”。
?????? 下載地址:
? ? ? ?? http://www.crummy.com/software/BeautifulSoup/
? ? ? ?? http://www.crummy.com/software/BeautifulSoup/bs4/download/4.3/
? ? ? ? 安裝過程如下圖所示:python setup.py install
? ? ? ? 具體使用方法建議參照中文:
? ? ? ??http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html
? ? ? ? 其中BeautifulSoup的用法簡單講解下,使用“愛麗絲夢游仙境”的官方例子: #!/usr/bin/python # -*- coding: utf-8 -*- from bs4 import BeautifulSouphtml_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://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><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://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>? ? ? ? 下面是BeautifulSoup庫簡單快速入門介紹:(參考:官方文檔)
'''獲取title值''' print soup.title # <title>The Dormouse's story</title> print soup.title.name # title print unicode(soup.title.string) # The Dormouse's story'''獲取<p>值''' print soup.p # <p class="title"><b>The Dormouse's story</b></p> print soup.a # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>'''從文檔中找到<a>的所有標簽鏈接''' print soup.find_all('a') # [<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('a'):print(link.get('href'))# http://example.com/elsie# http://example.com/lacie# http://example.com/tillie print soup.find(id='link3') # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>? ? ? ? 如果想獲取文章中所有文字內容,代碼如下:
'''從文檔中獲取所有文字內容''' print soup.get_text() # The Dormouse's story # # The Dormouse'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 BeautifulSouphtml = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title" id="start"><b>The Dormouse's story</b></p> """ soup = BeautifulSoup(html) tag = soup.p print tag # <p class="title" id="start"><b>The Dormouse's story</b></p> print type(tag) # <class 'bs4.element.Tag'> print tag.name # p 標簽名字 print tag['class'] # [u'title'] print tag.attrs # {u'class': [u'title'], u'id': u'start'}? ? ? ? 使用BeautifulSoup每個tag都有自己的名字,可以通過.name來獲取;同樣一個tag可能有很多個屬性,屬性的操作方法與字典相同,可以直接通過“.attrs”獲取屬性。至于修改、刪除操作請參考文檔。
? ? ? ? 2.NavigableString
? ? ? ? 字符串常被包含在tag內,Beautiful Soup用NavigableString類來包裝tag中的字符串。一個NavigableString字符串與Python中的Unicode字符串相同,并且還支持包含在遍歷文檔樹和搜索文檔樹中的一些特性,通過unicode()方法可以直接將NavigableString對象轉換成Unicode字符串。
print unicode(tag.string) # The Dormouse's story print type(tag.string) # <class 'bs4.element.NavigableString'> tag.string.replace_with("No longer bold") print tag # <p class="title" id="start"><b>No longer bold</b></p>? ? ? ? 這是獲取“<p class="title" id="start"><b>The Dormouse's story</b></p>”中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 'bs4.element.Comment'> print unicode(comment) # Hey, buddy. Want to buy a used parser?? ? ? ? 介紹完這四個對象后,下面簡單介紹遍歷文檔樹和搜索文檔樹及常用的函數。
? ? ? ? 5.遍歷文檔樹
? ? ? ? 一個Tag可能包含多個字符串或其它的Tag,這些都是這個Tag的子節點。BeautifulSoup提供了許多操作和遍歷子節點的屬性。引用官方文檔中愛麗絲例子:
? ? ? ? 操作文檔最簡單的方法是告訴你想獲取tag的name,如下: soup.head # <head><title>The Dormouse's story</title></head>soup.title # <title>The Dormouse's story</title> soup.body.b # <b>The Dormouse's story</b> ? ? ? ? 注意:通過點取屬性的放是只能獲得當前名字的第一個Tag,同時可以在文檔樹的tag中多次調用該方法如soup.body.b獲取<body>標簽中第一個<b>標簽。
? ? ? ? 如果想得到所有的<a>標簽,使用方法find_all(),在前面的Python爬取維基百科等HTML中我們經常用到它+正則表達式的方法。
soup.find_all('a') # [<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>] ? ? ? ? 子節點:在分析HTML過程中通常需要分析tag的子節點,而tag的 .contents 屬性可以將tag的子節點以列表的方式輸出。字符串沒有.contents屬性,因為字符串沒有子節點。
head_tag = soup.head head_tag # <head><title>The Dormouse's story</title></head>head_tag.contents [<title>The Dormouse's story</title>]title_tag = head_tag.contents[0] title_tag # <title>The Dormouse's story</title> 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)# <title>The Dormouse's story</title># The Dormouse's story ? ? ? ? 父節點:通過 .parent 屬性來獲取某個元素的父節點.在例子“愛麗絲”的文檔中,<head>標簽是<title>標簽的父節點,換句話就是增加一層標簽。
? ? ? ? 注意:文檔的頂層節點比如<html>的父節點是 BeautifulSoup 對象,BeautifulSoup 對象的 .parent 是None。
title_tag = soup.title title_tag # <title>The Dormouse's story</title> title_tag.parent # <head><title>The Dormouse's story</title></head>title_tag.string.parent # <title>The Dormouse's story</title> ? ? ? ? 兄弟節點:因為<b>標簽和<c>標簽是同一層:他們是同一個元素的子節點,所以<b>和<c>可以被稱為兄弟節點。一段文檔以標準格式輸出時,兄弟節點有相同的縮進級別.在代碼中也可以使用這種關系。
sibling_soup = BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>") print(sibling_soup.prettify()) # <html> # <body> # <a> # <b> # text1 # </b> # <c> # text2 # </c> # </a> # </body> # </html> ? ? ? ? 在文檔樹中,使用 .next_sibling 和 .previous_sibling 屬性來查詢兄弟節點。<b>標簽有.next_sibling 屬性,但是沒有.previous_sibling 屬性,因為<b>標簽在同級節點中是第一個。同理<c>標簽有.previous_sibling 屬性,卻沒有.next_sibling 屬性:
sibling_soup.b.next_sibling # <c>text2</c>sibling_soup.c.previous_sibling # <b>text1</b> ? ? ? ? 介紹到這里基本就可以實現我們的BeautifulSoup庫爬取網頁內容,而網頁修改、刪除等內容建議大家閱讀文檔。下一篇文章就再次爬取維基百科的程序語言的內容吧!希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵!建議大家閱讀官方文檔和《Python基礎教程》書。
? ? ? ? (By:Eastmount 2015-3-25 下午6點 ?http://blog.csdn.net/eastmount/)
總結
以上是生活随笔為你收集整理的[python知识] 爬虫知识之BeautifulSoup库安装及简单介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [python学习] 简单爬取图片网站图
- 下一篇: [python+nltk] 自然语言处理