2016-01-20 33 views
0

我得到一個頁面urllib2,然後解析它與lxml。通常有兩件事情可以去錯了:一個urllib2.URLError,或​​結合'雖然不是'與嘗試/除了

def get_page(url): 
    response = None 
    while not response: 
     try: 
      response = urllib2.urlopen(url) 
     except urllib2.URLError: 
      response = urllib2.urlopen(url) 
     except httplib.IncompleteRead: 
      print '**** IncompleteRead for response from %s, retrying' % url 
     html_parser = etree.HTMLParser() 
     tree = etree.parse(response, html_parser) 
     return tree 

有幾個明顯的問題在這裏:

  1. 第一except做同樣的事情作爲其先前try
  2. 無論我們是否有response,我們都會嘗試解析lxml

所以:

  1. 什麼需要在第一except去?是pass可以接受嗎?
  2. 我的理解是在try內只應該嘗試一個單獨的動作,所以我不願意移動下面的解析。事實上,一個函數本身應該只執行一個動作 - 解析是否屬於它自己的函數?
+2

如果你想在兩種情況下重試,你可以使用'except(urllib2.URLError,httplib.IncompleteRead):'來處理具有相同代碼的兩個異常。 –

+0

也許'繼續'? – Ryan

+0

「這裏有幾個明顯的問題」 - 這些問題對我們來說並不明顯,因爲您實際上沒有描述代碼應該執行什麼操作。例如如果引發'URLError'會發生什麼?如果引發'IncompleteRead'會發生什麼? – mgilson

回答

3

您可以使用continuebreak陳述的組合處理這些情況。 continue將跳回到while循環的頂部,break將跳出while循環。

def get_page(url): 
    response = None 
    while not response: 
     try: 
      response = urllib2.urlopen(url) 
     except urllib2.URLError: 
      continue # No response, try again 
     except httplib.IncompleteRead: 
      print '**** IncompleteRead for response from %s, retrying' % url 
      break # Bad response, don't try again? 
     html_parser = etree.HTMLParser() 
     tree = etree.parse(response, html_parser) 
     return tree 

有(其中被執行只有當exeception 塊中發生像else子句try)其他流動控制工具,你可以在這裏中的比重,以及:

try: 
    pass 
except Exception as err: 
    print("Don't see this.") 
else: 
    print("You will see this.") 

,而不是:

try: 
    raise Exception 
except Exception as err: 
    print("You will see this.") 
else: 
    print("Don't see this.") 
1

我想你想將解析移出while循環,而不是移入try塊。這樣,您可以繼續循環嘗試獲取有效的響應,並且只嘗試解析請求是否成功。

def get_page(url): 
    response = None 
    while not response: 
     try: 
      response = urllib2.urlopen(url) 
     except urllib2.URLError: 
      print '**** URLError for response from %s, retrying' % url 
     except httplib.IncompleteRead: 
      print '**** IncompleteRead for response from %s, retrying' % url 

    html_parser = etree.HTMLParser() 
    tree = etree.parse(response, html_parser) 
    return tree 

我還更新了except塊爲URLError基本上工作一樣IncompeleteRead塊。我不太確定這是否合適,因爲某些URLError可能無法通過重試來修復(例如,如果服務器不存在,那麼在您重試時可能不會更改)。如果它應該是一個致命錯誤(至少對這個函數是致命的),那麼您可能需要在該except塊中使用raise,而不是讓循環繼續。下面是治療URLErrors嚴肅認真得多IncompleteRead個版本:

def get_page(url): 
    response = None 
    while not response: 
     try: 
      response = urllib2.urlopen(url) 
     except urllib2.URLError: 
      print '**** URLError for response from %s, giving up' % url 
      raise 
     except httplib.IncompleteRead: 
      print '**** IncompleteRead for response from %s, retrying' % url 

    html_parser = etree.HTMLParser() 
    tree = etree.parse(response, html_parser) 
    return tree 

raise關鍵字本身(後無表達)重新引發當前異常。如果這會在您的應用程序中更有意義(例如,一個ValueError,表示提供的URL不好)。