2017-06-17 97 views
2

假设我有一些像这样的(简化)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() 

在初始find_all返回一个异常的情况下,我希望所有字典条目是'None'。在任何单个字典分配的情况下都会返回一个异常,我想要'无'。

有什么好的方法来写这个,除了像下面这样可怕的东西吗?

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' 
+0

这是故意的,其中一些是“无”和其他“无”? –

+0

另一方面,您的解决方案与其他建议的解决方案具有相同的行数(或更少),并立即清楚您要做什么。也许它并不像你想象的那么可怕...... – pbuck

+0

@pbuck,好吧,对于三项词典,它可能与其他“更普遍”的解决方案一样短。你打算如何处理100个项目的词典? – makeiteasy

回答

0

创建自己的类

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 
0

这里就是我可以建议你的代码:

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 

或者,你可以创建一个函数,将处理异常你:

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() 
0

我去的解决方案是创建一个空白的模板字典(实际上是一个JSON),所有的键都设置为'None'。

每次页面被抓取时,m_stats首先使用这个空白字典(从JSON加载)初始化。如果发生异常,它只是简单地通过(有一些日志记录),并且值保留为'None'。那么不需要每次都明确地分配“无”。

不知道将此标记为“答案”是否正确,因为它与我的需求非常具体,但这就是我所做的。