处理表式网站结构的BeautifulSoup | returning dictionary

2024-10-02 14:19:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些html,那种看起来像字典:

制造商网站:

总部:地点等 ..

每个部分都包含在自己的div中(因此findAll,div类名)

有没有一种优雅而简单的方法将这些代码提取到字典中?或者必须遍历每个div,找到两个文本项,并假设第一个文本项是dictionary的键,第二个值是同一dict元素的值

站点代码示例:

    car = '''
     <div class="info flexbox">
       <div class="infoEntity">
        <span class="manufacturer website">
         <a class="link" href="http://www.ford.com" rel="nofollow noreferrer" target="_blank">
          www.ford.com
         </a>
        </span>
       </div>
       <div class="infoEntity">
        <label>
         Headquarters
        </label>
        <span class="value">
         Dearbord, MI
        </span>
       </div>
       <div class="infoEntity">
        <label>
         Model
        </label>
        <span class="value">
         Mustang
        </span>
       </div>
    '''

car_soup = BeautifulSoup(car, 'lxml')
print(car_soup.prettify())

elements = car_soup.findAll('div', class_ = 'infoEntity')
for x in elements:
    print(x)  ###and then we start iterating over x, with beautiful soup, to find value of each element.

期望的输出是这样的

expected result result = {'manufacturer website':"ford.com", 'Headquarters': 'Dearborn, Mi', 'Model':'Mustang'}

顺便说一句,在这一点上,我已经做了几次不优雅的方式,只是想知道我是否遗漏了什么,是否有更好的方式来做到这一点。提前谢谢


Tags: 代码文本divcom字典valuecarlabel
2条回答

当前的HTML结构非常通用,它包含多个infoEntitydiv,子内容可以通过多种方式格式化。要处理此问题,可以迭代infoEntitydiv并应用格式化对象,如下所示:

from bs4 import BeautifulSoup as soup
result, label = {}, None
for i in soup(car, 'html.parser').find_all('div', {'class':'infoEntity'}):
   for b in i.find_all(['span', 'label']):
      if b.name == 'label':
         label = b.get_text(strip=True)
      elif b.name == 'span' and label is not None:
         result[label] = b.get_text(strip=True)
         label = None
      else:
         result[' '.join(b['class'])] = b.get_text(strip=True)

输出:

{'manufacturer website': 'www.ford.com', 'Headquarters': 'Dearbord, MI', 'Model': 'Mustang'}

或者,为了使事情更加通用和简单,您可以使用标签和制造商网站链接拆分字段处理:

soup = BeautifulSoup(car, 'lxml')

car_info = soup.select_one('.info')
data = {
    label.get_text(strip=True): label.find_next_sibling().get_text(strip=True)
    for label in car_info.select('.infoEntity label')
}
data['manufacturer website'] = car_info.select_one('.infoEntity a').get_text(strip=True)

print(data)

印刷品:

{'Headquarters': 'Dearbord, MI', 
 'Model': 'Mustang', 
 'manufacturer website': 'www.ford.com'}

相关问题 更多 >