4

HTMLを解析するためにpyparsingを使用しています。私はすべてのタグを取得していますembedが、場合によっては、タグがすぐ後に続く場合もあります。a

例:

import pyparsing
target = pyparsing.makeHTMLTags("embed")[0]
target.setParseAction(pyparsing.withAttribute(src=pyparsing.withAttribute.ANY_VALUE))
target.ignore(pyparsing.htmlComment)

result = target.searchString(""".....
   <object....><embed>.....</embed></object><br /><a href="blah">blah</a>
   """)

結果オブジェクトで文字オフセットを見つけることができませんでした。それ以外の場合は、元の入力文字列のスライスを取得して、そこから作業することができます。

編集:

私が BeautifulSoup を使わない理由を誰かが尋ねました。これは良い質問です。コード サンプルを使用して、なぜそれを使用しないことにしたかをお見せしましょう。

import BeautifulSoup
import urllib
import re
import socket

socket.setdefaulttimeout(3)

# get some random blogs
xml = urllib.urlopen('http://rpc.weblogs.com/shortChanges.xml').read()

success, failure = 0.0, 0.0

for url in re.compile(r'\burl="([^"]+)"').findall(xml)[:30]:
    print url
    try:
        BeautifulSoup.BeautifulSoup(urllib.urlopen(url).read())
    except IOError:
        pass
    except Exception, e:
        print e
        failure += 1
    else:
        success += 1


print failure / (failure + success)

これを試してみると、 20 ~ 30% の確率で BeautifulSoup が解析エラーで失敗します。これらはまれなエッジ ケースではありません。pyparsing は遅くて面倒ですが、何を投げても爆発しませんでした。BeautifulSoup のより良い使用方法について教えていただければ、それを知りたいと思います。

4

4 に答える 4

5

<a>タグに続く場合に興味深いオプションのタグがある場合は<embed>、それを検索パターンに追加します。

embedTag = pyparsing.makeHTMLTags("embed")[0]
aTag = pyparsing.makeHTMLTags("a")[0]
target = embedTag + pyparsing.Optional(aTag)
result = target.searchString(""".....   
    <object....><embed>.....</embed></object><br /><a href="blah">blah</a>
    """)

print result.dump()

パーサー内の式の文字位置を取得する場合は、結果の名前を付けて次のいずれかを挿入します。

loc = pyparsing.Empty().setParseAction(lambda s,locn,toks: locn)
target = loc("beforeEmbed") + embedTag + loc("afterEmbed") + 
                                                 pyparsing.Optional(aTag)
于 2009-11-20T04:02:28.767 に答える
1

なぜ独自のHTMLパーサーを作成するのですか?標準ライブラリにはHTMLParserが含まれており、BeautifulSoupはHTMLParserが処理できないすべてのジョブを処理できます。

于 2009-11-20T01:02:12.067 に答える
1

通常の正規表現を使用したくないですか?または、html を解析する悪い習慣のためですか? :D

re.findall("<object.*?</object>(?:<br /><a.*?</a>)?",a)
于 2009-11-20T15:21:13.810 に答える
1

BeautifulSoup コードを実行できましたが、エラーは発生しませんでした。BeautifulSoup 3.0.7a を実行しています

BeautifulSoup 3.0.7a を使用してください。3.1.0.1 にはバグがあり、場合によってはまったく動作しません (あなたの場合など)。

于 2009-11-20T19:48:25.453 に答える