简体   繁体   English

更好的尝试方式-多次检查除外

[英]Better way to try-except multiple checks

Suppose I have some (simplified) BeautifulSoup code like this, pulling data into a dictionary: 假设我有一些(简化的)BeautifulSoup代码,如下所示,将数据提取到字典中:

tournament_info = soup.find_all('li')

stats['Date'] = tournament_info[0].text
stats['Location'] = tournament_info[1].text
stats['Prize'] = tournament_info[3].text.split(':')[1].strip()

In the case where the initial find_all returns an exception, I want all the dictionary entries to be 'None'. 在初始find_all返回异常的情况下,我希望所有词典条目都为“ None”。 And in the case of any of the individual dictionary assignments returning an exception, I want 'None' too. 而且在任何单个字典分配返回异常的情况下,我也希望“无”。

Is there any nice way to write this, other than something horrible like below? 除了下面这样的可怕内容之外,还有什么写这种方法的好方法吗?

try:
    tournament_info = soup.find_all('li')
except:
    m_stats['Date'] = 'None'
    m_stats['Location'] = 'None'
    m_stats['Prize'] = 'None'

try:
    m_stats['Date'] = tournament_info[0].text
except:
    m_stats['Date'] = 'None'
try:
    m_stats['Location'] = tournament_info[1].text
except:
    m_stats['Location'] = 'None'
try:
    m_stats['Prize'] = tournament_info[3].text.split(':')[1].strip()
except:
    m_stats['Prize'] = 'None'

Here's what I can suggest for your code: 这是我对您的代码的建议:

info = soup.find_all('li')
if not info:
    m_stats = dict.fromkeys(m_stats, None)
    return

mappings = {
    'Date': 0,
    'Location': 1,
    'Prize': 3
}
for key in mappings:
    value = None
    try:
        value = info[mappings[key]].text
        if mappings[key] == 3:
            value = value.split(':')[1].strip()
    except IndexError:
        pass
    m_stats[key] = value

Alternatively, you can create a function that will handle the exceptions for you: 另外,您可以创建一个函数来为您处理异常:

def get_value(idx):
    value = None
    try:
        value = info[idx].text
    except IndexError:
        pass
    return value

m_stats['Date'] = get_value(0)
m_stats['Location'] = get_value(1)
m_stats['Prize'] = get_value(3)
if m_stats['Prize']:
    m_stats['Prize'].split(':')[1].strip()

Create own class 创建自己的课程

class Stats(dict):

    tournament_info = []

    def __init__(self, tournament_info, **kwargs):
        super(Stats, self).__init__(**kwargs)
        self.tournament_info = tournament_info
        self['Date'] = self.get_tournament_info_text(0)
        self['Location'] = self.get_tournament_info_text(1)
        prize = self.get_tournament_info_text(2)
        if prize is not None:
            prize = prize.split(':')[1].strip()
        self['Prize'] = prize

    def get_tournament_info_text(self, index):
        try:
            return self.tournament_info[index]['text']
        except:
            return None

tournament_info = [
    {
        'text': 'aaa'
    },
    {},
    {
        'text': 'bbb:ccc '
    }
]

m_stats = Stats(tournament_info)
print m_stats

The solution I went for was to create a blank template dictionary (actually a JSON) with all the keys set to 'None'. 我寻求的解决方案是创建一个空白模板字典(实际上是JSON),并将所有键设置为“无”。

Every time the page is scraped, m_stats is first initialised with this blank dictionary (loaded from the JSON). 每次抓取页面时,都会首先使用此空白字典(从JSON加载)初始化m_stats。 If an exception occurs, it is just simply passed (with some logging), and the value is left as 'None'. 如果发生异常,则只需将其传递(带有一些日志记录),并将该值保留为“ None”。 There is then no need to explicitly assign 'None' every single time. 这样就无需每次都明确地指定“无”。

Not sure if it's correct to mark this as the "answer", as it is quite specific to my needs, but that's what I did anyway. 不确定将其标记为“答案”是否正确,因为它完全符合我的需求,但这还是我要做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM