Жадное исполнение заявлений? - PullRequest
3 голосов
/ 06 ноября 2010

У меня есть что-то вроде этого, используя BeautifulSoup:

for line in lines:
    code = l.find('span', {'class':'boldHeader'}).text
    coded = l.find('div', {'class':'Description'}).text
    definition = l.find('ul', {'class':'definitions'}).text
    print code, coded, def

Однако не все элементы существуют во все времена. Я могу заключить это в попытку, за исключением того, чтобы это не прерывало выполнение программы следующим образом:

for line in lines:
    try:
      code = l.find('span', {'class':'boldHeader'}).text
      coded = l.find('div', {'class':'Description'}).text
      definition = l.find('ul', {'class':'definitions'}).text
      print code, coded, def
    except:
      pass

Но как я выполняю утверждения жадным способом? Например, если доступно только два элемента code и coded, я просто хочу получить их и продолжить выполнение. На данный момент, даже если code и coded существуют, если def не существует, команда печати никогда не выполняется.

Один из способов сделать это - поставить try...except для каждого утверждения, подобного этому:

for line in lines:
    try:
      code = l.find('span', {'class':'boldHeader'}).text
    except:
      pass
    try:
      coded = l.find('div', {'class':'Description'}).text
    except:
      pass
    try:
      definition = l.find('ul', {'class':'definitions'}).text
    except:
      pass
    print code, coded, def

Но это уродливый подход, и я хочу чего-нибудь чище. Есть предложения?

Ответы [ 2 ]

3 голосов
/ 06 ноября 2010

Как насчет захвата "уродливого" кода в функции и просто вызова функции по мере необходимости:

def get_txt(l,tag,classname):
    try:
        txt=l.find(tag, {'class':classname}).text
    except AttributeError:
        txt=None
    return txt

for line in lines:
    code = get_txt(l,'span','boldHeader')
    coded = get_txt(l,'div','Description')
    defn = get_txt(l,'ul','definitions')
    print code, coded, defn

PSЯ изменил def на defn, потому что def является ключевым словом Python.Использование его в качестве имени переменной вызывает ошибку SyntaxError.

PPS.Не рекомендуется использовать голые исключения:

try:
    ....
except:
    ...

, потому что это почти всегда захватывает больше, чем вы намереваетесь.Гораздо лучше четко указать, что вы хотите поймать:

try:
    ...
except AttributeError as err:
    ...
3 голосов
/ 06 ноября 2010

Прежде всего, вы можете проверить на None вместо того, чтобы поймать исключение. l.find должен вернуть None, если он не найдет ваш товар. Исключения должны быть зарезервированы для ошибок и действительно неординарных ситуаций.

Второе, что вы можете сделать, это создать массив всех элементов HTML, которые вы хотите проверить, и затем иметь вложенный цикл for. Поскольку я уже использовал python, я набросал код, а затем (надеюсь) отредактировал ответ при его тестировании.

Что-то вроде:

elementsToCheck = [
                  [ 'span', {'class':'boldHeader'} ],
                  [ 'div', {'class':'Description'} ],
                  [ 'ul', {'class':'definitions'} ]]

concatenated = ''
for line in lines:
    for something in elementsToCheck
       element = l.find(something[0], something[1])
       if element is not None
          concatenated += element.text
print concatenated

Очевидно, что приведенный выше код не будет работать, но вы должны понять это. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...