9

我正在解析显示项目数据的网站上的网页。这些项目有大约 20 个可能出现也可能不出现的字段——比如:价格、数量、最后购买、高、低等。

我目前正在使用一系列命令;大约 20 行soup.find('div',{'class':SOME_FIELD_OF_INTEREST})来查找每个单独的感兴趣领域。(有些在div, span, dd, 等等,所以很难只做一个soup.find_all('div')命令。)

我的问题:是否有一种优雅的方式tryexcept一切,使得所述代码的查看可以更紧凑或更简洁?现在,示例行如下所示:

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

我希望将所有内容组合在一行中。我认为我不能在语法上运行 try: <line of code> except: <code>,而且我不确定如何编写一个try_command(soup.find('div',{'id':'item-pic'}).img["src"])无需实际运行命令的函数。

我很想听听是否有人有任何建议(包括:“这不可能/不切实际,继续前进”)。:)

编辑:聊了一会儿,我想我想看看内联异常处理的好做法是什么,以及这是否是正确的途径。

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在许多情况下代替字符串。例如:

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 回答