9

アイテム データを表示するサイトの Web ページを解析しています。これらのアイテムには、発生する場合と発生しない場合がある約 20 のフィールドがあります。たとえば、価格、数量、最後に購入したもの、高値、安値などです。

現在、一連のコマンドを使用しています。soup.find('div',{'class':SOME_FIELD_OF_INTEREST})関心のある分野ごとに約 20 行を探します。( 、 、 などに入っているものもあるdivのでspanddコマンドだけでは難しいsoup.find_all('div')です。)

私の質問:上記のコードの表示をよりコンパクトまたは簡潔にするためのエレガントな方法はtryありますか? except現在、サンプル行は次のようになります。

try:
    soup.find('div', {'id':'item-pic'}).img["src"]
except:
    ""

すべてを1行にまとめたいと思っていました。構文的に try: を実行できるとは思いません。実際にコマンドを実行せずに<line of code> except: <code>関数を作成する方法がわかりません。try_command(soup.find('div',{'id':'item-pic'}).img["src"])

誰かにアドバイスがあればぜひ聞きたいです(「これは不可能/実用的ではありません、先に進んでください」など)。:)

EDIT:少し話した後、インライン例外処理の良い習慣とは何か、そしてそれが正しいルートであるかどうかを見たかったと思います。

4

2 に答える 2

1

たぶんそのようなもの:

def try_these(start_obj, *args) :
        obj = start_obj
        for trythat in args :
            if obj is None :
                return None
            try :
                if isinstance(trythat, str) :
                    obj = getattr(obj, trythat)
                else :
                    method, opts = trythat
                    obj = getattr(obj, method)(*opts)
            except :
                return None
        return obj    
src = try_these(soup, ('find', ({'id':'item-pic'},),), 
                      'img', 
                      ('get', ('src',),) )

strオブジェクトから属性を取得するために渡すことができる場所またはtuple(strメソッド、タプルパラメーター)、最終的に取得Noneまたは結果になります。私はスープに慣れていないのでget('src')、良いアプローチになるかどうかはわかりません (おそらく口述ではないため)。とにかく、そのスニペットを簡単に変更して、「呼び出しまたは属性」以外のものを受け入れることができます。


あなたの質問に触発されて、そのような状況に対処するのに役立つ簡単なpythonモジュールを書きました。ここで見つけることができます

import silentcrawler    

wrapped = silentcrawler.wrap(soup)
# just return None on failure
print wrapped.find('div', {'id':'item-pic'}).img["src"].value_

# or
def on_success(value) :
    print 'found value:', value
wrapped = silentcrawler.wrap(soup, success=on_success)
# call on_success if everything will be ok
wrapped.find('div', {'id':'item-pic'}).img["src"].value_ 

もっと可能性がある

于 2012-12-09T02:48:37.080 に答える
1

私の理解が正しければ、興味深いクラス名に基づいていくつかのフィールドを見つけたいと考えていますが、同じ要素である必要はありません (すべてではない<div>) 。

その場合、BeautifulSoup を使用すると、コンパイル済みの正規表現 (re.compile多くの場合、文字列の代わりに from から) を渡すことができます。例:

print soup.findAll(re.compile(".*"), {'class': 'blah'})
# [<div class="blah"></div>, <span class="blah"></span>]

これを使用して、画像を含む可能性のある関連するすべての DOM 要素をきちんとループすることができます。

import re
import urllib

from BeautifulSoup import BeautifulSoup as BS


html = """
<html>
<body>
<div class="blah"></div>
<span class="blah"><img src="yay.jpg"></span>
<span class="other"></div>

</body>
</html>
"""

def get_img_src(soup, cssclass):
    for item in soup.findAll(re.compile(".*"), {'class': cssclass}):
        if item.img is not None and 'src' in dict(item.img.attrs):
            return item.img['src']


soup = BS(html)
img = get_img_src(soup, cssclass = "blah")
print img # outputs yay.jpg, or would return None if nothing was found

if議論の余地がありますが、この場合はチェックを使用する方が適切だと思います。item.img['src']

同様に次のように書くこともできます。

def get_img_src(soup, cssclass):
    for item in soup.findAll(re.compile(".*"), {'class': cssclass}):
        try:
            return item.img['src']
        except TypeError:
            pass

..しかし、ここでキャッチするのは奇妙TypeErrorです ('NoneType' object has no attribute '__getitem__'実際にキャッチしようとしている例外ではないため、属性にアクセスするために BeautifulSoup で使用される構文の副産物です)

于 2012-12-09T21:00:56.633 に答える