2017-06-17 21 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'。那麼不需要每次都明確地分配「無」。

不知道將此標記爲「答案」是否正確,因爲它與我的需求非常具體,但這就是我所做的。

相關問題