Beautiful Soup 4 常見問題

2021-05-24 09:15 更新

本章節(jié)總結(jié)了一些 Beautiful Soup 4 的常見問題,有遇到相關(guān)問題可以按照相應(yīng)的措施進(jìn)行處理。

代碼診斷

如果想知道Beautiful Soup到底怎樣處理一份文檔,可以將文檔傳入 ?diagnose()? 方法(Beautiful Soup 4.2.0中新增),Beautiful Soup會(huì)輸出一份報(bào)告,說明不同的解析器會(huì)怎樣處理這段文檔,并標(biāo)出當(dāng)前的解析過程會(huì)使用哪種解析器:

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ù)制出來以便尋求他人的幫助

文檔解析錯(cuò)誤

文檔解析錯(cuò)誤有兩種.一種是崩潰,Beautiful Soup嘗試解析一段文檔結(jié)果卻拋除了異常,通常是 ?HTMLParser.HTMLParseError? .還有一種異常情況,是Beautiful Soup解析后的文檔樹看起來與原來的內(nèi)容相差很多.

這些錯(cuò)誤幾乎都不是Beautiful Soup的原因,這不會(huì)是因?yàn)锽eautiful Soup得代碼寫的太優(yōu)秀,而是因?yàn)锽eautiful Soup沒有包含任何文檔解析代碼.異常產(chǎn)生自被依賴的解析器,如果解析器不能很好的解析出當(dāng)前的文檔,那么最好的辦法是換一個(gè)解析器.更多細(xì)節(jié)查看 安裝解析器 章節(jié).

最常見的解析錯(cuò)誤是 ?HTMLParser.HTMLParseError: malformed start tag? 和 ?HTMLParser.HTMLParseError: bad end tag? .這都是由Python內(nèi)置的解析器引起的,解決方法是 安裝lxml或html5lib

最常見的異常現(xiàn)象是當(dāng)前文檔找不到指定的Tag,而這個(gè)Tag光是用眼睛就足夠發(fā)現(xiàn)的了. ?find_all()? 方法返回,而 ?find()? 方法返回 None .這是Python內(nèi)置解析器的又一個(gè)問題: 解析器會(huì)跳過那些它不知道的tag.解決方法還是 安裝lxml或html5lib

版本錯(cuò)誤

  • ?SyntaxError: Invalid syntax? (異常位置在代碼行: ?ROOT_TAG_NAME = u'[document]'? ),因?yàn)镻ython2版本的代碼沒有經(jīng)過遷移就在Python3中窒息感
  • ?ImportError: No module named HTMLParser? 因?yàn)樵赑ython3中執(zhí)行Python2版本的Beautiful Soup
  • ?ImportError: No module named html.parser? 因?yàn)樵赑ython2中執(zhí)行Python3版本的Beautiful Soup
  • ?ImportError: No module named BeautifulSoup? 因?yàn)樵跊]有安裝BeautifulSoup3庫(kù)的Python環(huán)境下執(zhí)行代碼,或忘記了BeautifulSoup4的代碼需要從 ?bs4? 包中引入
  • ?ImportError: No module named bs4? 因?yàn)楫?dāng)前Python環(huán)境下還沒有安裝BeautifulSoup4

解析成XML

默認(rèn)情況下,Beautiful Soup會(huì)將當(dāng)前文檔作為HTML格式解析,如果要解析XML文檔,要在 ?BeautifulSoup? 構(gòu)造方法中加入第二個(gè)參數(shù) “xml”:

soup = BeautifulSoup(markup, "xml")

當(dāng)然,還需要 安裝lxml

解析器的錯(cuò)誤

  • 如果同樣的代碼在不同環(huán)境下結(jié)果不同,可能是因?yàn)閮蓚€(gè)環(huán)境下使用不同的解析器造成的.例如這個(gè)環(huán)境中安裝了lxml,而另一個(gè)環(huán)境中只有html5lib, 解析器之間的區(qū)別 中說明了原因.修復(fù)方法是在 ?BeautifulSoup? 的構(gòu)造方法中中指定解析器
  • 因?yàn)镠TML標(biāo)簽是 大小寫敏感 的,所以3種解析器再出來文檔時(shí)都將tag和屬性轉(zhuǎn)換成小寫.例如文檔中的 <TAG></TAG> 會(huì)被轉(zhuǎn)換為 <tag></tag> .如果想要保留tag的大寫的話,那么應(yīng)該將文檔 解析成XML .

雜項(xiàng)錯(cuò)誤

  • ?UnicodeEncodeError: 'charmap' codec can't encode character u'\xfoo' in position bar? (或其它類型的 ?UnicodeEncodeError? )的錯(cuò)誤,主要是兩方面的錯(cuò)誤(都不是Beautiful Soup的原因),第一種是正在使用的終端(console)無法顯示部分Unicode,參考 Python wiki ,第二種是向文件寫入時(shí),被寫入文件不支持部分Unicode,這時(shí)只要用 ?u.encode("utf8")? 方法將編碼轉(zhuǎn)換為UTF-8.
  • ?KeyError: [attr]? 因?yàn)檎{(diào)用 ?tag['attr']? 方法而引起,因?yàn)檫@個(gè)tag沒有定義該屬性.出錯(cuò)最多的是 ?KeyError: 'href'? 和 ?KeyError: 'class'? .如果不確定某個(gè)屬性是否存在時(shí),用 ?tag.get('attr')? 方法去獲取它,跟獲取Python字典的key一樣
  • ?AttributeError: 'ResultSet' object has no attribute 'foo'? 錯(cuò)誤通常是因?yàn)榘?nbsp;?find_all()? 的返回結(jié)果當(dāng)作一個(gè)tag或文本節(jié)點(diǎn)使用,實(shí)際上返回結(jié)果是一個(gè)列表或 ?ResultSet? 對(duì)象的字符串,需要對(duì)結(jié)果進(jìn)行循環(huán)才能得到每個(gè)節(jié)點(diǎn)的 ?.foo? 屬性.或者使用 ?find()? 方法僅獲取到一個(gè)節(jié)點(diǎn)
  • ?AttributeError: 'NoneType' object has no attribute 'foo'? 這個(gè)錯(cuò)誤通常是在調(diào)用了 ?find()? 方法后直節(jié)點(diǎn)取某個(gè)屬性 .foo 但是 ?find()? 方法并沒有找到任何結(jié)果,所以它的返回值是 ?None? .需要找出為什么 ?find()? 的返回值是 ?None? .

如何提高效率

Beautiful Soup對(duì)文檔的解析速度不會(huì)比它所依賴的解析器更快,如果對(duì)計(jì)算時(shí)間要求很高或者計(jì)算機(jī)的時(shí)間比程序員的時(shí)間更值錢,那么就應(yīng)該直接使用 lxml .

換句話說,還有提高Beautiful Soup效率的辦法,使用lxml作為解析器.Beautiful Soup用lxml做解析器比用html5lib或Python內(nèi)置解析器速度快很多.

安裝 cchardet 后文檔的解碼的編碼檢測(cè)會(huì)速度更快

解析部分文檔 不會(huì)節(jié)省多少解析時(shí)間,但是會(huì)節(jié)省很多內(nèi)存,并且搜索時(shí)也會(huì)變得更快.


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)