web-dev-qa-db-ja.com

Pythonを使用してHTMLをプレーンテキストにレンダリング

BeautifulSoupを使用してHTMLテキストのチャンクを変換しようとしています。以下に例を示します。

<div>
    <p>
        Some text
        <span>more text</span>
        even more text
    </p>
    <ul>
        <li>list item</li>
        <li>yet another list item</li>
    </ul>
</div>
<p>Some other text</p>
<ul>
    <li>list item</li>
    <li>yet another list item</li>
</ul>

私は次のようなことをしようとしました:

def parse_text(contents_string)
    Newlines = re.compile(r'[\r\n]\s+')
    bs = BeautifulSoup.BeautifulSoup(contents_string, convertEntities=BeautifulSoup.BeautifulSoup.HTML_ENTITIES)
    txt = bs.getText('\n')
    return Newlines.sub('\n', txt)

...しかし、そのように私のスパン要素は常に新しい行にあります。これはもちろん簡単な例です。 Pythonでブラウザにレンダリングされる方法としてHTMLページのテキストを取得する方法はありますか(CSSルールは不要で、div、span、liなどの要素が通常の方法でレンダリングされます)?

36
btatarov

BeautifulSoupはスクレイピングライブラリなので、おそらくHTMLレンダリングを行うための最良の選択ではありません。 BeautifulSoupを使用する必要がない場合は、 html2text 。例えば:

import html2text
html = open("foobar.html").read()
print html2text.html2text(html)

この出力:

] ____。] 
 *リスト項目
 *さらに別のリスト項目
82
del

レンダリングされたHTMLを解析しようとすると、同じ問題が発生していました。基本的に、BSはこのための理想的なパッケージではないようです。 @Delは、素晴らしいhtml2textソリューションを提供します。

DiffetetについてSO質問: BeautifulSoup get_textはすべてのタグとJavaScriptを削除しません @Helgeはnltkを使用して言及しました。残念ながらnltkはこの方法を中止しているようです。

私はhtml2textとnltk.clean_htmlの両方を試しましたが、タイミングの結果に驚いたので、後世への答えが必要だと思いました。もちろん、速度はデータの内容に大きく依存します...

@Helge(nltk)からの回答。

import nltk

%timeit nltk.clean_html(html)
was returning 153 us per loop

レンダリングされたhtmlで文字列を返すことは本当にうまくいきました。このnltkモジュールはhtml2textよりも高速でしたが、おそらくhtml2textはより堅牢です。

上記の@delからの回答

betterHTML = html.decode(errors='ignore')
%timeit html2text.html2text(betterHTML)
%3.09 ms per loop
4
Paul