我正在解析显示商品数据的网站上的网页。这些物品有大约20个可能会或可能不会发生的字段 - 例如:价格,数量,上次购买,高,低等。
我目前正在使用一系列命令;大约20行soup.find('div',{'class':SOME_FIELD_OF_INTEREST})
来查找每个单独的感兴趣的字段。 (有些位于div
,span
,dd
,依此类推,因此很难只执行soup.find_all('div')
命令。)
我的问题:try
和except
是否有一种优雅的方式,以便查看所述代码可以更紧凑或简洁?现在,样本行看起来像:
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"])
的函数。
我很想知道是否有人有任何建议(包括:“这不可能/不实用,继续前进”)。 :)
编辑:在谈了一下之后,我想我想看看内联异常处理的好习惯是什么,如果这是正确的路线。
答案 0 :(得分: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')
是否是一个好的方法(可能不是一个词典),无论如何你可以轻松地修改那个片段以接受更多的东西而不仅仅是'call或attr ”。
受你的问题的启发,我编写了简单的python模块,有助于处理这种情况,你可以找到它here
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_
有更多可能性
答案 1 :(得分: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用来访问属性的语法的副产品)