首页 > 解决方案 > 将多个没有类名的html标签解析为不同的变量

问题描述

所以在这个 HTML 中,我想用它们各自的值创建 python 变量,我已经抓取了 20K+ 的结果并且可以解析大部分数据,除了我不知道如何分解它,因为没有类名称,它们都在同一个 div 下。

<div class="callout callout-details">
  <h4>Details</h4>

  <dl class="dl-horizontal">
    <dt>Deadline:</dt>

    <dd>None</dd>

    <dt>Award type:</dt>

    <dd>Scholarship</dd>

    <dt>Award coverage:</dt>

    <dd>Other</dd>

    <dt>Renewable</dt>

    <dd>No</dd>

    <dt>Min. award:</dt>

    <dd>$2,000</dd>

    <dt>Average award:</dt>

    <dd>$2,000</dd>

    <dt>Max. award:</dt>

    <dd>$2,000</dd>

    <dt>Awarded anualy:</dt>

    <dd>No</dd>

    <dt>Unlimited awards:</dt>

    <dd>No</dd>

    <dt>Repay required:</dt>

    <dd>No</dd>
  </dl>
</div>

我能想到的唯一方法是将所有内容保存在里面<dl class="dl-horizontal">,然后拆分字符串,但我觉得这非常耗时,有没有什么我可以实现一个 for 循环并说

containers = page_soup.findAll("dl", {"class": "dl-horizontal"})
for container in containers:
     Deadline = container.dd
     Award = container.dd1 (and so on?)

我似乎无法弄清楚如何正确构建上述内容以覆盖所有dd领域。

标签: pythonhtmlparsingweb-scrapingbeautifulsoup

解决方案


由于它们是成对出现的,因此您可以使用切片将它们压缩在一起:

containers = page_soup.findAll("dl", {"class": "dl-horizontal"})
names = containers.children[::2]   # Every even elements (0, 2, 4, ...)
values = containers.children[1::2] # Every off  elements (1, 3, 5, ...)
for name, value in zip(names, values):
    print(name)  # ("Deadline:", "Award type:", ...) 
    print(value) # ("None",      "Scholarship", ...)

切片是这样的,考虑一下列表a,你可以做到a[start:end:step]。它将返回一个新列表,从start值开始直到前一个end(它不包括它)。并且将仅包括每个stepnd 值。

a = ['a', 'b', 'c', 'd']

# Leaving start blank is same as 0.
# And leaving end blank is same as the length of a, so include all elements
a[:]     => ['a', 'b', 'c', 'd']
a[::2]   => ['a', 'c']
a[1::2]  => ['b', 'd']

# Zip groups elements of multiple lists aligned
zip(a[::2], a[1::2]) => [('a', 'b'), ('c', 'd')]

推荐阅读