【问题标题】:BeautifulSoup, a dictionary from an HTML tableBeautifulSoup,来自 HTML 表的字典
【发布时间】:2012-08-10 12:38:52
【问题描述】:

我正在尝试从网站上抓取表格数据。

这是一个简单的示例表:

t = '<html><table>' +\
    '<tr><td class="label"> a </td> <td> 1 </td></tr>' +\
    '<tr><td class="label"> b </td> <td> 2 </td></tr>' +\
    '<tr><td class="label"> c </td> <td> 3 </td></tr>' +\
    '<tr><td class="label"> d </td> <td> 4 </td></tr>' +\
    '</table></html>'

想要的解析结果是{' a ': ' 1 ', ' b ': ' 2 ', ' c ': ' 3 ', ' d ' : ' 4' }


这是我迄今为止最接近的尝试:

for tr in s.findAll('tr'):
  k, v = BeautifulSoup(str(tr)).findAll('td')
  d[str(k)] = str(v)

结果是:

{'<td class="label"> a </td>': '<td> 1 </td>', '<td class="label"> d </td>': '<td> 4 </td>', '<td class="label"> b </td>': '<td> 2 </td>', '<td class="label"> c </td>': '<td> 3 </td>'}

我知道findAll()text=True 参数,但我使用它时没有得到预期的结果。

我正在使用 python 2.6 和 BeautifulSoup3。

【问题讨论】:

  • 您好——非常感谢这个伟大的例子——这真的很有帮助,也是一个很好的例子——它向我展示了如何使用基本的 python 数据结构。顺便说一句,我们能否将这个很棒的迷你课程应用到现实世界的示例中 - 例如维基百科上的表格 - 我很高兴收到你的来信 - 关于零

标签: python beautifulsoup


【解决方案1】:

试试这个:

from BeautifulSoup import BeautifulSoup, Comment

t = '<html><table>' +\
    '<tr><td class="label"> a </td> <td> 1 </td></tr>' +\
    '<tr><td class="label"> b </td> <td> 2 </td></tr>' +\
    '<tr><td class="label"> c </td> <td> 3 </td></tr>' +\
    '<tr><td class="label"> d </td> <td> 4 </td></tr>' +\
    '</table></html>'

bs = BeautifulSoup(t)

results = {}
for row in bs.findAll('tr'):
    aux = row.findAll('td')
    results[aux[0].string] = aux[1].string

print results

【讨论】:

    【解决方案2】:

    BeautifulSoup 和 Python 已经进化,所以如果有人带着更新的版本来到这里:

    Python>=3.7
    BeautifulSoup>=4.7
    

    以下是有效的更新代码:

    # import bs4 and create your 'soup' object
    
    table = soup.find('table')
    
    headers = [header.text for header in table.find_all('th')]
    results = [{headers[i]: cell for i, cell in enumerate(row.find_all('td'))}
               for row in table.find_all('tr')]
    

    【讨论】:

    • 嗨,亲爱的 Martin Martin .- 太好了:我喜欢这种方法:目前我正在学习 python,我发现使用 bs4 这样做非常有帮助:您的代码显示了如何创建汤-对象:- 非常感谢这个好例子 - 这真的很有帮助,也是一个很好的例子 - 它向我展示了如何使用基本的 python 数据结构。顺便说一句,我们能否将这个很棒的迷你课程应用到现实世界的示例中 - 例如维基百科上的表格 - 我很高兴收到你的来信 - 关于零
    • 您好@zero - 查看Beautiful Soup: Build A Web Scraper in Python 上的教程以获取一个示例,该示例将引导您通过真实示例的整个抓取过程。希望对您有所帮助并继续学习! :)
    【解决方案3】:

    如果您要抓取的表格有明确的“thead”和“tbody”,例如:

    <table>
        <thead>
            <tr>
                <th>Total</th>
                <th>Finished</th>
                <th>Unfinished</th>
            </tr>
        </thead>
        <tbody>
            <tr> <td>63</td> <td>33</td> <td>2</td> </tr>
            <tr> <td>69</td> <td>29</td> <td>3</td> </tr>
            <tr> <td>57</td> <td>28</td> <td>1</td> </tr>
        </tbody>
    </table>
    

    您可以使用以下内容:

    headers = [header.text_content() for header in table.cssselect("thead tr th")]
    results = [{headers[i]: cell.text_content() for i, cell in enumerate(row.cssselect("td"))} for row in table.cssselect("tbody tr")]
    

    这将产生:

    [
      {"Total": "63", "Finished": "33", "Unfinished": "2"},
      {"Total": "69", "Finished": "29", "Unfinished": "3"},
      {"Total": "57", "Finished": "28", "Unfinished": "1"}
    ]
    

    附:这是使用 lxml.html。如果您使用 BeautifulSoup,请将“.text_content()”替换为“.string”,将“.cssselect”替换为“.findAll”。

    【讨论】:

      【解决方案4】:

      您可以采用与mvillaress 相同的方法,但稍作改进,使用List Comprehensions

      from BeautifulSoup import BeautifulSoup
      
      t = '<html><table>' +\
          '<tr><td class="label"> a </td> <td> 1 </td></tr>' +\
          '<tr><td class="label"> b </td> <td> 2 </td></tr>' +\
          '<tr><td class="label"> c </td> <td> 3 </td></tr>' +\
          '<tr><td class="label"> d </td> <td> 4 </td></tr>' +\
          '</table></html>'
      
      bs = BeautifulSoup(t)
      tds = [row.findAll('td') for row in bs.findAll('tr')]
      results = { td[0].string: td[1].string for td in tds }
      print results
      

      【讨论】:

        【解决方案5】:

        这是一个我认为更接近原始尝试的解决方案:

        d={}
        for tr in soup.findAll('tr'):
            key = tr.text.split()[0]
            val = tr.text.split()[1]
            d[key] = val
        
        print(d)
        

        【讨论】:

          猜你喜欢
          • 2021-11-05
          • 1970-01-01
          • 1970-01-01
          • 2011-07-30
          • 1970-01-01
          • 1970-01-01
          • 2013-08-13
          • 1970-01-01
          相关资源
          最近更新 更多