Это, возможно, гораздо более широкий вопрос, чем мой вариант использования.
Я использую Beautifulsoup для извлечения данных из HTML-документов.
Для тех, кто не знаком с Beautifulsoup, это по сути парсинг HTMLСтрока и использование методов класса для поиска и выделения определенных данных, с учетом явной инструкции.
Шаг первый: soup = Beautifulsoup(html_string)
Шаг второй: title= soup.find('h1').get_text()
Шаг первый анализируетВ документе, шаг два, содержится инструкция о том, какие данные извлекать, и, в вышеупомянутом случае, используя get_text()
, также некоторое форматирование.
У меня обычно есть список таких действий, в которых данные могут присутствовать или не присутствовать,и любое условие является приемлемым.Например, на ряде страниц профиля некоторые пользователи могут вводить или не вводить favorite_color
, favorite_movie
или etc
.Если эти данные есть, я хочу их, но если нет, то значение None
в порядке.
Обычно я подхожу к этим случаям так:
soup = Beautifulsoup(html)
try:
data_one = soup.find('div', class_='data_one').get_text()
except AttributeError as e:
data_one = None
try:
data_two= soup.find('div', class_='data_two').get_text()
except AttributeError as e:
data_two= None
try:
data_three = soup.find('div', class_='data_three ').get_text()
except AttributeError as e:
data_three = None
Как можно себе представить, мойфайлы быстро становятся большими и трудными для навигации.
Какой самый СУХОЙ способ приблизиться к этому?
ПРИМЕЧАНИЕ. В моем случае использования каждые Блок try:except
будет обращаться к одному классу исключений, AttributeError
, который представляет данные, отсутствующие в html.
ПРИМЕЧАНИЕ. Я ищу что-то, что не ограничивало бы тип метода извлечения.Например, это то, что я хотел бы также использовать:
try:
list_items = [x.get_text() for x in soup.find('div', class_='first').find_all('li', class_='first-child') and x.find('a', class_='conditional-link') is not None]
except AttributeError as e:
list_items = None
ОБНОВЛЕНИЕ 12/30/2018 Я все еще чувствую, что принятый ответ является наиболее правильным подходом.Я также чувствую, что это немного абстрактно по сравнению с другими подходами.Я хотел бы включить альтернативный подход здесь.Во-первых, позвольте мне сказать, что одной из основных проблем, которые пытается решить этот вопрос, является дальнейший доступ к данным с Beautifulsoup, когда они могут не быть данными.Например, метод get_text()
вызывает AttributeError
для элементов класса NoneType
.
Это альтернативный подход, когда такая дополнительная спецификация необходима для извлечения данных из списка элементов, которые могут включать или не включать элементы NoneType
:
# Get Initial Elements (NoneType assigned if Error)
data_one = soup.find('element', class_='e_one class_name')
data_two = soup.find('elemment', value='1')
data_three = soup.find('element', class_='parent').find('div', class_='name')
# Further parsing/extraction if element is not NoneType Object
data = [x.get_text(strip=True) if x is not None for x in [data_one, data_two, data_three]]
Это ничегореволюционный, но, кажется, обеспечивает очень плавный способ объединения некоторых частей кода.