使用BeautifulSoup还是正则表达式将HTML表转换为数据结构?

0 投票
2 回答
977 浏览
提问于 2025-04-16 04:14

我有一个HTML表格,想从中提取信息。不过,有些表格跨越了多行或多列,所以我想用类似BeautifulSoup的工具把表格解析成某种Python结构。我在想,可能可以用一个列表的列表来处理,把类似这样的内容:

<tr>
  <td>1,1</td>
  <td>1,2</td>
</tr>
<tr>
  <td>2,1</td>
  <td>2,2</td>
</tr>

转换成:

[['1,1', '1,2'],
 ['2,1', '2,2']]

我觉得这应该比较简单。不过,有一些小麻烦,因为有些单元格跨越了多行或多列。而且还有很多完全不必要的信息:

    <td ondblclick="DoAdd('/student_center/sc_all_rooms/d05/09/2010/editformnew?display=W&amp;style=L&amp;positioning=A&amp;adddirect=yes&amp;accessid=CreateNewEdit&amp;filterblock=N&amp;popeditform=yes&amp;returncalendar=student_center/sc_all_rooms')"
     class="listdefaultmonthbg" 
     style="cursor:crosshair;" 
     width="5%" 
     nowrap="1" 
     rowspan="1">
       <a class="listdatelink" 
          href="/student_center/sc_all_rooms/d05/09/2010/edit?style=L&amp;display=W&amp;positioning=A&amp;filterblock=N&amp;adddirect=yes&amp;accessid=CreateNewEdit">Sep 5</a>
    </td>

实际上,代码看起来更复杂。我真正需要的只是:

<td rowspan="1">Sep 5</td>

两行之后,有一个单元格的rowspan是17。对于多行合并,我在想可以这样处理:

<tr>
  <td rowspan="2">Sep 5</td>
  <td>Some event</td>
</tr>
<tr>
  <td>Some other event</td>
</tr>

最后会变成这样:

[["Sep 5", "Some event"],
 [None, "Some other event"]]

页面上有多个表格,我已经找到了我想要的那个,只是不知道怎么提取我需要的信息。我知道可以用BeautifulSoup的“RenderContents”,但在某些情况下,有些链接标签我需要去掉(同时保留文本)。

我在想可以按照这样的步骤进行:

  1. 找到表格
  2. 计算表格中的行数(len(table.findAll('tr'))?)
  3. 创建列表
  4. 把表格解析成列表(BeautifulSoup的语法???)
  5. ???
  6. 赚到钱!(好吧,这只是一个内部程序,所以其实没什么收益……)

2 个回答

0

你可能需要通过一些属性,比如id或者name,来找到那个表格。

from BeautifulSoup import BeautifulSoup

data = """
<table>
<tr>
  <td>1,1</td>
  <td>1,2</td>
</tr>
<tr>
  <td>2,1</td>
  <td>2,2</td>
</tr>
</table>
"""

soup = BeautifulSoup(data)

for t in soup.findAll('table'):
    for tr in t.findAll('tr'):
        print [td.contents for td in tr.findAll('td')]

补充:如果有多个链接,程序应该怎么处理呢?

例如:

<td><a href="#">A</a> B <a href="#">C</a></td>
2

最近在LinkedIn的python小组里,有人讨论了一个类似的问题,看来lxml是最受推荐的用于解析html页面的python工具。

http://www.linkedin.com/groupItem?view=&gid=25827&type=member&item=27735259&qid=d2948a0e-6c0c-4256-851b-5e7007859553&goback=.gmp_25827

撰写回答