【问题标题】:Unable to store parsed items as dictionary无法将解析的项目存储为字典
【发布时间】:2017-12-09 16:54:45
【问题描述】:

我在 python 中编写了一个小脚本,使用 BeautifulSoup 从以下脚本中 content 变量中存储的某些元素中解析出一些项目。我不希望将项目附加到先前创建的空字典中;相反,我希望动态解析它。但是,我尝试了但无法实现。任何帮助将不胜感激。

这是我的尝试:

from bs4 import BeautifulSoup

content="""
<table class="data">
    <tbody>
        <tr class="blue">
            <td>hot</td>
            <td>cold</td>
        </tr>
        <tr>
            <td>day</td>
            <td>night</td>
        </tr>
    </tbody>
</table>
"""
soup = BeautifulSoup(content,'lxml')
for items in soup.select('tr'):
    data = [item.text for item in items.select("td")]
    dict_val = {data[0] : data[1]}
    print(dict_val)

我得到输出的方式:

{'hot': 'cold'}
{'day': 'night'}

我期望的输出方式:

{'hot': 'cold','day': 'night'}

【问题讨论】:

  • 提示:dict_val 是在每次迭代时创建的新字典。

标签: python python-3.x dictionary web-scraping


【解决方案1】:

您可以在 for 循环之外创建字典:

soup = BeautifulSoup(content,'lxml')
d = {}
for items in soup.select('tr'):
   data = [item.text for item in items.select("td")]
   d[data[0]] = data[1]
print(d)

或者,您可以在一行中创建一个字典:

from bs4 import BeautifulSoup as soup
s = [i.text for i in soup(content, 'lxml').findAll('td')]
new_s = dict([s[i:i+2] for i in range(0, len(s), 2)])

输出:

{u'hot': u'cold', u'day': u'night'}

【讨论】:

  • 这不是字典理解。 {s[i]: s[i+1] for i in range(0, len(s), 2)}
  • 您是否运行了最新版本来验证它是否有效?
【解决方案2】:

请记住,计算机只会完全按照您的指示行事。您的原始代码有这一行:

dict_val = {data[0] : data[1]}

这会在每次循环迭代时创建一个新字典。相反,如果您想创建一个字典并向其中添加元素,则需要这样做。通常用文字写出步骤会有所帮助:

create a dictionary
for each row in the table:
    parse the <td> elements from the row
    add an entry to the dictionary

您已经将其中的大部分内容翻译成 Python。主要区别在于创建字典的位置以及如何将 HTML 中的数据插入到字典中。我将把如何在 Python 中执行此操作的细节留作练习。 (提示:查看另一个答案。)这里重要的是清楚地考虑您要执行的步骤的顺序,然后然后弄清楚如何在 Python 中执行。

【讨论】:

    【解决方案3】:

    您需要在 for 循环之前初始化字典,在您的代码中,每次迭代都会在这一行 dict_val = {data[0] : data[1]} 中创建一个新字典。你可以试试下面的代码:

    from bs4 import BeautifulSoup
    
    content="""
    <table class="data">
        <tbody>
            <tr class="blue">
                <td>hot</td>
                <td>cold</td>
            </tr>
            <tr>
                <td>day</td>
                <td>night</td>
            </tr>
        </tbody>
    </table>
    """
    soup = BeautifulSoup(content,'lxml')
    dict_val = {}
    for items in soup.select('tr'):
        data = [item.text for item in items.select("td")]
        dict_val[data[0]] = data[1]
    print(dict_val)
    

    【讨论】:

      【解决方案4】:

      将 nth-child 与 bs4 4.7.1 和字典理解一起使用。特定于示例的解决方案,如图所示。

      from bs4 import BeautifulSoup
      
      content="""
      <table class="data">
          <tbody>
              <tr class="blue">
                  <td>hot</td>
                  <td>cold</td>
              </tr>
              <tr>
                  <td>day</td>
                  <td>night</td>
              </tr>
          </tbody>
      </table>
      """
      soup = BeautifulSoup(content,'lxml')
      result = {k.text:v.text for (k,v) in zip(soup.select('.data  tr:nth-child(odd) td'), soup.select('.data  tr:nth-child(even) td'))}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-08
        相关资源
        最近更新 更多