这可能是一个比我的用例更广泛的问题。
我正在使用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]]
这不是革命性的,但似乎提供了一种非常流畅的方式来整合代码的某些部分。
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
更具体的处理方式可能是循环遍历类值列表:
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)