Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python try/except: trying multiple options

I'm trying to scrape some information from webpages that are inconsistent about where the info is located. I've got code to handle each of several possibilities; what I want is to try them in sequence, then if none of them work I'd like to fail gracefully and move on.

That is, in psuedo-code:

try:
    info = look_in_first_place()
otherwise try:
    info = look in_second_place()
otherwise try:
    info = look_in_third_place()
except AttributeError:
    info = "Info not found"

I could do this with nested try statements, but if I need 15 possibilities to try then I'll need 15 levels of indentation!

This seems like a trivial enough question that I feel like I'm missing something, but I've searched it into the ground and can't find anything that looks equivalent to this situation. Is there a sensible and Pythonic way to do this?

EDIT: As John's (pretty good) solution below raises, for brevity I've written each lookup above as a single function call, whereas in reality it's usually a small block of BeautifulSoup calls such as soup.find('h1', class_='parselikeHeader'). Of course I could wrap these in functions, but it seems a bit inelegant with such simple blocks -- apologies if my shorthand changes the problem though.

This may be a more useful illustration:

try:
    info = soup.find('h1', class_='parselikeHeader').get('href')
if that fails try:
    marker = soup.find('span', class_='header')
    info = '_'.join(marker.stripped_strings)
if that fails try:
    (other options)
except AttributeError:
    info = "Info not found"
like image 759
user3816044 Avatar asked Jul 08 '14 11:07

user3816044


1 Answers

If each lookup is a separate function, you can store all the functions in a list and then iterate over them one by one.

lookups = [
    look_in_first_place,
    look_in_second_place,
    look_in_third_place
]

info = None

for lookup in lookups:
    try:
        info = lookup()
        # exit the loop on success
        break    
    except AttributeError:
        # repeat the loop on failure
        continue

# when the loop is finished, check if we found a result or not
if info:
    # success
else:
    # failure
like image 135
John Kugelman Avatar answered Nov 05 '22 08:11

John Kugelman