【问题标题】:BeautifulSoup (Python) and parsing HTML tableBeautifulSoup (Python) 和解析 HTML 表
【发布时间】:2011-06-15 09:19:01
【问题描述】:

##### 更新 ###### :renderContents() 而不是 contents[0] 成功了。如果有人可以提供更好、更优雅的解决方案,我仍然会保持开放!

我正在尝试解析一些网页以获得所需的数据。该表没有类/ID 标记。所以我必须在 tr 内容中搜索“网站”。

手头的问题: 显示 td.contents 仅适用于文本而不是超链接,出于某种原因?我究竟做错了什么?有没有更好的方法在 Python 中使用 bs 来做到这一点?

那些建议 lxml 的人,我有一个正在进行的线程 herecentOS 和没有管理员权限的 lxml 安装在这个时候被证明是少数。因此探索 BeautifulSoup 选项。

HTML 示例:

                   <table border="2" width="100%">
                      <tbody><tr>
                        <td width="33%" class="BoldTD">Website</td>
                        <td width="33%" class="BoldTD">Last Visited</td>
                        <td width="34%" class="BoldTD">Last Loaded</td>
                      </tr>
                      <tr>
                        <td width="33%">
                          <a href="http://google.com"></a>
                        </td>
                        <td width="33%">01/14/2011
                                </td>
                        <td width="34%">
                                </td>
                      </tr>
                      <tr>
                        <td width="33%">
                          stackoverflow.com
                        </td>
                        <td width="33%">01/10/2011
                                </td>
                        <td width="34%">
                                </td>
                      </tr>
                      <tr>
                        <td width="33%">
                          <a href="http://stackoverflow.com"></a>
                        </td>
                        <td width="33%">01/10/2011
                                </td>
                        <td width="34%">
                                </td>
                      </tr>
                    </tbody></table>

到目前为止的 Python 代码:

        f1 = open(PATH + "/" + FILE)
        pageSource = f1.read()
        f1.close()
        soup = BeautifulSoup(pageSource)
        alltables = soup.findAll( "table", {"border":"2", "width":"100%"} )
        print "Number of tables found : " , len(alltables)

        for table in alltables:
            rows = table.findAll('tr')
            for tr in rows:
                cols = tr.findAll('td')
                for td in cols:
                    print td.contents[0]

【问题讨论】:

  • 应该 &lt;a href="http://google.com"&lt;/a&gt;&lt;a href="http://google.com"&gt;&lt;/a&gt; (即是否缺少 &gt;?)
  • 更新了缺少>的HTML,还是不行。

标签: python beautifulsoup html-table html-parsing


【解决方案1】:
from BeautifulSoup import BeautifulSoup

pageSource='''...omitted for brevity...'''    

soup = BeautifulSoup(pageSource)
alltables = soup.findAll( "table", {"border":"2", "width":"100%"} )

results=[]
for table in alltables:
    rows = table.findAll('tr')
    lines=[]
    for tr in rows:
        cols = tr.findAll('td')
        for td in cols:
            text=td.renderContents().strip('\n')
            lines.append(text)
    text_table='\n'.join(lines)
    if 'Website' in text_table:
        results.append(text_table) 
print "Number of tables found : " , len(results)
for result in results:
    print(result)

产量

Number of tables found :  1
Website
Last Visited
Last Loaded
<a href="http://google.com"></a>
01/14/2011

stackoverflow.com
01/10/2011

<a href="http://stackoverflow.com"></a>
01/10/2011

这与您正在寻找的内容相近吗? 问题是td.contents 返回NavigableStrings 和汤tags 的列表。例如,运行print(td.contents) 可能会产生

['', '<a href="http://stackoverflow.com"></a>', '']

所以选择列表的第一个元素会让你错过&lt;a&gt;-tag。

【讨论】:

  • 是的,这非常接近,但如果另一个表具有相同的“边框”、“宽度”值和不需要的内容,那就是个问题。如何仅限于那些在其中包含“网站”的表格(表格内容)?顺便说一句,非常感谢!
  • 我已经编辑了代码来展示如何只选择那些包含字符串“网站”的代码。我不知道“网站”是否永远是表格的第一行,所以我以更通用的方式编写了代码——在整个表格的任何地方搜索“网站”。如果您只想在第一行搜索“网站”,我将分别处理行 [0],测试“网站”,然后使用 for tr in rows[1:]: 遍历其余行。
【解决方案2】:

我回答了一个类似的问题here。希望对你有帮助。

外行解决方案:

alltables = soup.findAll( "table", {"border":"2", "width":"100%"} )

t = [x for x in soup.findAll('td')]

[x.renderContents().strip('\n') for x in t]

输出:

['Website',
 'Last Visited',
 'Last Loaded',
 '<a href="http://google.com"></a>',
 '01/14/2011\n                                ',
 '',
 '                          stackoverflow.com\n                        ',
 '01/10/2011\n                                ',
 '',
 '<a href="http://stackoverflow.com"></a>',
 '01/10/2011\n                                ',
 '']

【讨论】:

  • 感谢您的链接,但我在解析表格时遇到问题,而不仅仅是锚标记。在这种情况下,td 内容之一是 URL,我想获取 标记中包含的所有内容。
猜你喜欢
  • 2020-02-06
  • 2014-03-06
  • 2011-07-21
  • 2018-07-10
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 2011-01-04
  • 2018-02-01
相关资源
最近更新 更多