巩固尝试:除Beaufifulsoup4中的区块外

问题描述 投票:1回答:3

这可能是一个比我的用例更广泛的问题。

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

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

第一步: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

正如人们可能想象的那样,我的文件很快变得庞大且难以导航。

最干的方法是什么?

注意:在我的用例中,每个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]]

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

python beautifulsoup try-catch dry
3个回答
2
投票

或者,您可以以getattr()方式使用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)

1
投票

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

0
投票

更具体的处理方式可能是循环遍历类值列表:

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)
© www.soinside.com 2019 - 2024. All rights reserved.