在 Beaufifulsoup4 中合并 Try:Except 个块

Consolidating Try:Except blocks in Beaufifulsoup4

这可能比我的用例所提出的问题要广泛得多。

我正在使用 Beautifulsoup 从 html 文档中提取数据。

对于那些不熟悉 Beautifulsoup 的人,它本质上是解析 html 字符串并使用 class 方法搜索和隔离某些数据,给出明确的指令。

第一步: soup = Beautifulsoup(html_string)

第二步: title= soup.find('h1').get_text()

第一步解析文档,第二步提供有关提取哪些数据的说明,在上述情况下使用 get_text(),还进行一些格式化。

我通常有一个此类操作的列表,其中数据可能存在也可能不存在,并且任一条件都可以接受。例如,在一系列个人资料页面上,某些用户可能输入或未输入 favorite_colorfavorite_movieetc。如果该数据在那里,我想要它,但如果没有,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

正如人们想象的那样,我的文件很快就会变大并且难以浏览。

的方法是什么?

注意:在我的用例中,every try:except 块将解决单个异常 class,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      

2018 年 12 月 30 日更新 我仍然觉得接受的答案是最正确的做法。我也觉得与其他方法相比,它有点抽象。我想在这里包括一个替代方法。首先,让我说这个问题试图解决的核心问题之一是在 Beautifulsoup 可能不是数据时进一步访问数据。例如,get_text() 方法在属于 NoneType class 的元素上引发 AttributeError

这是一种替代方法,需要进一步规范才能从可能包含或不包含 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]]

这不是革命性的,但似乎提供了一种非常流畅的方式来整合一些部分代码。

Extract a method:

def get_text_or_none(element)
    try:
        return element.get_text()
    except AttributeError:
        return None

data_one = get_text_or_none(soup.find('div', class_='data_one'))
data_two = get_text_or_none(soup.find('div', class_='data_two'))
data_three = get_text_or_none(soup.find('div', class_='data_three'))

这是EAFP方法。

LBYL 人们会这样做:

return element.get_text() if element else None

更具体的处理方式可能是遍历 class 个值的列表:

classes = ['data_one', 'data_two', 'data_three']

result = {}
for class_value in classes:
    try:
        result[class_value] = soup.find('div', class_=class_value).get_text()
    except AttributeError:
        result[class_value]

print(result)

或者,您可以使用 getattr() built-in function in an LBYL 方式:

data_one = getattr(soup.find('div', class_='data_one'), 'text', None)
data_two = getattr(soup.find('div', class_='data_two'), 'text', None)
data_three = getattr(soup.find('div', class_='data_three'), 'text', None)