日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

[python知识] 爬虫知识之BeautifulSoup库安装及简单介绍

發(fā)布時間:2024/5/28 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [python知识] 爬虫知识之BeautifulSoup库安装及简单介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一. 前言

? ? ? ? 在前面的幾篇文章中我介紹了如何通過Python分析源代碼來爬取博客、維基百科InfoBox和圖片,其文章鏈接如下:
? ? ? ? [python學(xué)習(xí)] 簡單爬取維基百科程序語言消息盒
? ? ? ??[Python學(xué)習(xí)] 簡單網(wǎng)絡(luò)爬蟲抓取博客文章及思想介紹
? ? ? ? [python學(xué)習(xí)] 簡單爬取圖片網(wǎng)站圖庫中圖片
? ? ? ? 其中核心代碼如下:

# coding=utf-8 import urllib import re#下載靜態(tài)HTML網(wǎng)頁 url='http://www.csdn.net/' content = urllib.urlopen(url).read() open('csdn.html','w+').write(content) #獲取標題 title_pat=r'(?<=<title>).*?(?=</title>)' title_ex=re.compile(title_pat,re.M|re.S) title_obj=re.search(title_ex, content) title=title_obj.group() print title #獲取超鏈接內(nèi)容 href = r'<a href=.*?>(.*?)</a>' m = re.findall(href,content,re.S|re.M) for text in m:print unicode(text,'utf-8')break #只輸出一個url ? ? ? ? 輸出結(jié)果如下:
>>> CSDN.NET - 全球最大中文IT社區(qū),為IT專業(yè)技術(shù)人員提供最全面的信息傳播和服務(wù)平臺 登錄 >>> ??????? 圖片下載的核心代碼如下:
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來爬取網(wǎng)站內(nèi)容的方法存在很多弊端,譬如:
? ? ? ? 1.正則表達式被HTML源碼所約束,而不是取決于更抽象的結(jié)構(gòu);網(wǎng)頁結(jié)構(gòu)中很小的改動可能會導(dǎo)致程序的中斷。
? ? ? ? 2.程序需要根據(jù)實際HTML源碼分析內(nèi)容,可能會遇到字符實體如&amp;之類的HTML特性,需要指定處理如<span></span>、圖標超鏈接、下標等不同內(nèi)容。
? ? ? ? 3.正則表達式并不是完全可讀的,更復(fù)雜的HTML代碼和查詢表達式會變得很亂。
? ? ? ? 正如《Python基礎(chǔ)教程(第2版)》采用兩種解決方案:第一個是使用Tidy(Python庫)的程序和XHTML解析;第二個是使用BeautifulSoup庫。


二. 安裝及介紹Beautiful Soup庫


? ? ? ?Beautiful Soup是用Python寫的一個HTML/XML的解析器,它可以很好的處理不規(guī)范標記并生成剖析樹(parse tree)。 它提供簡單又常用的導(dǎo)航navigating,搜索以及修改剖析樹的操作。它可以大大節(jié)省你的編程時間。
? ? ? 正如書中所說“那些糟糕的網(wǎng)頁不是你寫的,你只是試圖從中獲得一些數(shù)據(jù)。現(xiàn)在你不用關(guān)心HTML是什么樣子的,解析器幫你實現(xiàn)”。
??????
下載地址:
? ? ? ?? 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())? ? ? ?輸出內(nèi)容按照標準的縮進格式的結(jié)構(gòu)輸出如下:
<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>? ? ? ? 如果想獲取文章中所有文字內(nèi)容,代碼如下:
'''從文檔中獲取所有文字內(nèi)容''' 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
? ? ? ? 當(dāng)你成功安裝BeautifulSoup 4庫后,“from BeautifulSoup import BeautifulSoup”可能會遇到該錯誤。

? ? ? ? 其中的原因是BeautifulSoup 4庫改名為bs4,需要使用“from bs4 import BeautifulSoup”導(dǎo)入。
? ? ? ? 2.TypeError: an integer is required
? ? ? ? 當(dāng)你使用“print soup.title.string”獲取title的值時,可能會遇到該錯誤。如下:

? ? ? ? 它應(yīng)該是IDLE的BUG,當(dāng)使用命令行Command沒有任何錯誤。參考:stackoverflow。同時可以通過下面的代碼解決該問題:
? ? ? ? print unicode(soup.title.string)
? ? ? ? print str(soup.title.string)


三. Beautiful Soup常用方法介紹


? ? ? ?
Beautiful Soup將復(fù)雜HTML文檔轉(zhuǎn)換成一個復(fù)雜的樹形結(jié)構(gòu),每個節(jié)點都是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內(nèi),Beautiful Soup用NavigableString類來包裝tag中的字符串。一個NavigableString字符串與Python中的Unicode字符串相同,并且還支持包含在遍歷文檔樹搜索文檔樹中的一些特性,通過unicode()方法可以直接將NavigableString對象轉(zhuǎn)換成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中包含的字符串不能編輯,但可通過函數(shù)replace_with()替換。
? ? ? ? NavigableString 對象支持遍歷文檔樹和搜索文檔樹 中定義的大部分屬性, 并非全部。尤其是一個字符串不能包含其它內(nèi)容(tag能夠包含字符串或是其它tag),字符串不支持 .contents 或 .string 屬性或 find() 方法。
? ? ? ? 如果想在Beautiful Soup之外使用 NavigableString 對象,需要調(diào)用 unicode() 方法,將該對象轉(zhuǎn)換成普通的Unicode字符串,否則就算Beautiful Soup已方法已經(jīng)執(zhí)行結(jié)束,該對象的輸出也會帶有對象的引用地址。這樣會浪費內(nèi)存。
? ? ? ? 3.Beautiful Soup對象
? ? ? ? 該對象表示的是一個文檔的全部內(nèi)容,大部分時候可以把它當(dāng)做Tag對象,它支持遍歷文檔樹和搜索文檔樹中的大部分方法。
? ? ? ? 注意:因為BeautifulSoup對象并不是真正的HTML或XML的tag,所以它沒有name和 attribute屬性,但有時查看它的.name屬性可以通過BeautifulSoup對象包含的一個值為[document]的特殊實行.name實現(xiàn)——soup.name。
? ? ? ??Beautiful Soup中定義的其它類型都可能會出現(xiàn)在XML的文檔中:CData , ProcessingInstruction , Declaration , Doctype 。與 Comment 對象類似,這些類都是 NavigableString 的子類,只是添加了一些額外的方法的字符串獨享。
? ? ? ? 4.Command注釋
? ? ? ? Tag、NavigableString、BeautifulSoup幾乎覆蓋了html和xml中的所有內(nèi)容,但是還有些特殊對象容易讓人擔(dān)心——注釋。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?? ? ? ? 介紹完這四個對象后,下面簡單介紹遍歷文檔樹和搜索文檔樹及常用的函數(shù)。
? ? ? ? 5.遍歷文檔樹
? ? ? ? 一個Tag可能包含多個字符串或其它的Tag,這些都是這個Tag的子節(jié)點。BeautifulSoup提供了許多操作和遍歷子節(jié)點的屬性。引用官方文檔中愛麗絲例子:
? ? ? ? 操作文檔最簡單的方法是告訴你想獲取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> ? ? ? ? 注意:通過點取屬性的放是只能獲得當(dāng)前名字的第一個Tag,同時可以在文檔樹的tag中多次調(diào)用該方法如soup.body.b獲取<body>標簽中第一個<b>標簽。
? ? ? ? 如果想得到所有的<a>標簽,使用方法find_all(),在前面的Python爬取維基百科等HTML中我們經(jīng)常用到它+正則表達式的方法。
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>] ? ? ? ? 子節(jié)點:在分析HTML過程中通常需要分析tag的子節(jié)點,而tag的 .contents 屬性可以將tag的子節(jié)點以列表的方式輸出。字符串沒有.contents屬性,因為字符串沒有子節(jié)點。
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的子節(jié)點進行循環(huán):
for child in title_tag.children:print(child)# The Dormouse's story ? ? ? ? 子孫節(jié)點:同樣?.descendants 屬性可以對所有tag的子孫節(jié)點進行遞歸循環(huán):
for child in head_tag.descendants:print(child)# <title>The Dormouse's story</title># The Dormouse's story ? ? ? ? 父節(jié)點:通過 .parent 屬性來獲取某個元素的父節(jié)點.在例子“愛麗絲”的文檔中,<head>標簽是<title>標簽的父節(jié)點,換句話就是增加一層標簽。
? ? ? ? 注意:文檔的頂層節(jié)點比如<html>的父節(jié)點是 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> ? ? ? ? 兄弟節(jié)點:因為<b>標簽和<c>標簽是同一層:他們是同一個元素的子節(jié)點,所以<b>和<c>可以被稱為兄弟節(jié)點。一段文檔以標準格式輸出時,兄弟節(jié)點有相同的縮進級別.在代碼中也可以使用這種關(guān)系。
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 屬性來查詢兄弟節(jié)點。<b>標簽有.next_sibling 屬性,但是沒有.previous_sibling 屬性,因為<b>標簽在同級節(jié)點中是第一個。同理<c>標簽有.previous_sibling 屬性,卻沒有.next_sibling 屬性:
sibling_soup.b.next_sibling # <c>text2</c>sibling_soup.c.previous_sibling # <b>text1</b> ? ? ? ? 介紹到這里基本就可以實現(xiàn)我們的BeautifulSoup庫爬取網(wǎng)頁內(nèi)容,而網(wǎng)頁修改、刪除等內(nèi)容建議大家閱讀文檔。下一篇文章就再次爬取維基百科的程序語言的內(nèi)容吧!希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵!建議大家閱讀官方文檔和《Python基礎(chǔ)教程》書。
? ? ? ? (By:Eastmount 2015-3-25 下午6點 ?http://blog.csdn.net/eastmount/)


總結(jié)

以上是生活随笔為你收集整理的[python知识] 爬虫知识之BeautifulSoup库安装及简单介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。