9

PythonとBeautifulSoupを使用して、HTMLファイルをマークアップしようとしています(文字列を「マーク」タグで文字通りラップしています)。問題は基本的に次のとおりです...

元の html ドキュメントがあるとします。

test = "<h1>oh hey</h1><div>here is some <b>SILLY</b> text</div>"

このドキュメント内の文字列を大文字と小文字を区別せずに (HTML を無視して) 検索し、「マーク」タグで囲みます。では、html で "ここにばかげたテキストがあります" を見つけたいとしましょう (太字のタグは無視します)。一致する html を取得して、「マーク」タグでラップしたいと思います。

たとえば、testで「here is some Silly text」を検索する場合、目的の出力は次のようになります。

"<h1>oh hey</h1><div><mark>here is some <b>SILLY</b> text</mark></div>"

何か案は?lxml や正規表現を使用する方が適切な場合は、それらのソリューションも受け入れます。

4

1 に答える 1

7
>>> soup = bs4.BeautifulSoup(test)
>>> matches = soup.find_all(lambda x: x.text.lower() == 'here is some silly text')
>>> for match in matches:
...     match.wrap(soup.new_tag('mark'))
>>> soup
<html><body><h1>oh hey</h1><mark><div>here is some <b>SILLY</b> text</div></mark></body></html>

比較する関数で引数を使用するだけでなく、比較する関数をnametoとして渡さなければならなかった理由は、明らかに必要な場合に後者がコンテンツを見つけられないためです。find_allx.text.lower()textx.lower()

場合によっては、このwrapように機能しない場合があります。そうでない場合は、代わりにenumerate(matches)、および設定する必要がありますmatches[i] = match.wrap(soup.new_tag('mark'))replace_with( を使用して、タグをそれ自体を参照する新しいタグに置き換えることはできません。)

また、意図したユース ケースで非 ASCII 文字列が一致する'here is some silly text'場合 (または非 ASCII 検索文字列を処理するようにコードを拡張する場合) は、上記の使用コードlower()が正しくない可能性があることに注意してください。を使用する代わりにstr.casefold()and/or locale.strxfrm(s)and/or を使用することもできますが、必要なものと、正しい答えを選択する方法を理解する必要があります。locale.strcoll(s, t)==

于 2013-05-28T20:31:51.820 に答える