本章節(jié)總結(jié)了一些 Beautiful Soup 4 的常見問題,有遇到相關(guān)問題可以按照相應(yīng)的措施進行處理。
如果想知道Beautiful Soup到底怎樣處理一份文檔,可以將文檔傳入 ?diagnose()
? 方法(Beautiful Soup 4.2.0中新增),Beautiful Soup會輸出一份報告,說明不同的解析器會怎樣處理這段文檔,并標出當(dāng)前的解析過程會使用哪種解析器:
from bs4.diagnose import diagnose
data = open("bad.html").read()
diagnose(data)
# Diagnostic running on Beautiful Soup 4.2.0
# Python version 2.7.3 (default, Aug 1 2012, 05:16:07)
# I noticed that html5lib is not installed. Installing it may help.
# Found lxml version 2.3.2.0
#
# Trying to parse your data with html.parser
# Here's what html.parser did with the document:
# ...
?diagnose()
? 方法的輸出結(jié)果可能幫助你找到問題的原因,如果不行,還可以把結(jié)果復(fù)制出來以便尋求他人的幫助
文檔解析錯誤有兩種.一種是崩潰,Beautiful Soup嘗試解析一段文檔結(jié)果卻拋除了異常,通常是 ?HTMLParser.HTMLParseError
? .還有一種異常情況,是Beautiful Soup解析后的文檔樹看起來與原來的內(nèi)容相差很多.
這些錯誤幾乎都不是Beautiful Soup的原因,這不會是因為Beautiful Soup得代碼寫的太優(yōu)秀,而是因為Beautiful Soup沒有包含任何文檔解析代碼.異常產(chǎn)生自被依賴的解析器,如果解析器不能很好的解析出當(dāng)前的文檔,那么最好的辦法是換一個解析器.更多細節(jié)查看 安裝解析器 章節(jié).
最常見的解析錯誤是 ?HTMLParser.HTMLParseError: malformed start tag
? 和 ?HTMLParser.HTMLParseError: bad end tag
? .這都是由Python內(nèi)置的解析器引起的,解決方法是 安裝lxml或html5lib
最常見的異?,F(xiàn)象是當(dāng)前文檔找不到指定的Tag,而這個Tag光是用眼睛就足夠發(fā)現(xiàn)的了. ?find_all()
? 方法返回,而 ?find()
? 方法返回 None .這是Python內(nèi)置解析器的又一個問題: 解析器會跳過那些它不知道的tag.解決方法還是 安裝lxml或html5lib
SyntaxError: Invalid syntax
? (異常位置在代碼行: ?ROOT_TAG_NAME = u'[document]'
? ),因為Python2版本的代碼沒有經(jīng)過遷移就在Python3中窒息感ImportError: No module named HTMLParser
? 因為在Python3中執(zhí)行Python2版本的Beautiful SoupImportError: No module named html.parser
? 因為在Python2中執(zhí)行Python3版本的Beautiful SoupImportError: No module named BeautifulSoup
? 因為在沒有安裝BeautifulSoup3庫的Python環(huán)境下執(zhí)行代碼,或忘記了BeautifulSoup4的代碼需要從 ?bs4
? 包中引入ImportError: No module named bs4
? 因為當(dāng)前Python環(huán)境下還沒有安裝BeautifulSoup4默認情況下,Beautiful Soup會將當(dāng)前文檔作為HTML格式解析,如果要解析XML文檔,要在 ?BeautifulSoup
? 構(gòu)造方法中加入第二個參數(shù) “xml”:
soup = BeautifulSoup(markup, "xml")
當(dāng)然,還需要 安裝lxml
BeautifulSoup
? 的構(gòu)造方法中中指定解析器UnicodeEncodeError: 'charmap' codec can't encode character u'\xfoo' in position bar
? (或其它類型的 ?UnicodeEncodeError
? )的錯誤,主要是兩方面的錯誤(都不是Beautiful Soup的原因),第一種是正在使用的終端(console)無法顯示部分Unicode,參考 Python
wiki ,第二種是向文件寫入時,被寫入文件不支持部分Unicode,這時只要用 ?u.encode("utf8")
? 方法將編碼轉(zhuǎn)換為UTF-8.KeyError: [attr]
? 因為調(diào)用 ?tag['attr']
? 方法而引起,因為這個tag沒有定義該屬性.出錯最多的是 ?KeyError: 'href'
? 和 ?KeyError: 'class'
? .如果不確定某個屬性是否存在時,用 ?tag.get('attr')
? 方法去獲取它,跟獲取Python字典的key一樣AttributeError: 'ResultSet' object has no attribute 'foo'
? 錯誤通常是因為把 ?find_all()
? 的返回結(jié)果當(dāng)作一個tag或文本節(jié)點使用,實際上返回結(jié)果是一個列表或 ?ResultSet
? 對象的字符串,需要對結(jié)果進行循環(huán)才能得到每個節(jié)點的 ?.foo
? 屬性.或者使用 ?find()
? 方法僅獲取到一個節(jié)點AttributeError: 'NoneType' object has no attribute 'foo'
? 這個錯誤通常是在調(diào)用了 ?find()
? 方法后直節(jié)點取某個屬性 .foo 但是 ?find()
? 方法并沒有找到任何結(jié)果,所以它的返回值是 ?None
? .需要找出為什么 ?find()
? 的返回值是 ?None
? .Beautiful Soup對文檔的解析速度不會比它所依賴的解析器更快,如果對計算時間要求很高或者計算機的時間比程序員的時間更值錢,那么就應(yīng)該直接使用 lxml .
換句話說,還有提高Beautiful Soup效率的辦法,使用lxml作為解析器.Beautiful Soup用lxml做解析器比用html5lib或Python內(nèi)置解析器速度快很多.
安裝 cchardet 后文檔的解碼的編碼檢測會速度更快
解析部分文檔 不會節(jié)省多少解析時間,但是會節(jié)省很多內(nèi)存,并且搜索時也會變得更快.
更多建議: