LoginSignup
5
4

More than 5 years have passed since last update.

Beautifulsoupがこぼれちゃう

Last updated at Posted at 2015-03-07

発端

某社のC++静的解析ツールが吐き出すレポート(HTML形式)から、必要なテキストだけを抜き出そうと思い立ち Python2.7 + Beautifulsoup4でごそごそと始めてみましたが…

bs4test.py
from bs4 import BeautifulSoup

soup = BeautifulSoup(open("rep_38248_dev1.html"))
print soup.prettify("shift_jis")

あれぇ? HTML全体(約2万6千行)の1/10の2500行ぐらいしか読み込まないじゃないか!!
弱った。参った。困った。

探索の旅

こういう時の常套手段は、「同じ境遇にいる人をネットで探す」です。
早速、googleで検索みると…どんびしゃな情報はありません。トほほ。

しかたがないので、bs4のソースコードであちこち突いて調べてみました。
原因は、bs4が下請けで呼び出している lxmlのfeed()メソッドの不具合で、巨大なHTMLテキストを食わせると途中でこぼれてしまうのでした。

対策は、bs4/builder/_lxml.py の LXMLTreeBuilder.feed() をコメントアウトするだけでOKです。(なぜか、XMLパーサーのLXMLTreeBuilderForXML.feed()は対策済みでした)

bs4/builder/_lxml.py
class LXMLTreeBuilder(HTMLTreeBuilder, LXMLTreeBuilderForXML):

    features = [LXML, HTML, FAST, PERMISSIVE]
    is_xml = False

    def default_parser(self, encoding):
        return etree.HTMLParser

#    def feed(self, markup):
#        encoding = self.soup.original_encoding
#        try:
#            self.parser = self.parser_for(encoding)
#            self.parser.feed(markup)
#            self.parser.close()
#        except (UnicodeDecodeError, LookupError, etree.ParserError), e:
#            raise ParserRejectedMarkup(str(e))

結末

あらためてググってみると、おや! Googleグループのbeautifulsoupフォーラムに関連するポストがありました。LXMLTreeBuilderForXML.feed() は、この時にBugFixされたようです。で、LXMLTreeBuilderの修正は漏れていた…ありゃまでした。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4