1

次のようなテーブルをBeautifulSoupで解析して、各人の名前、年齢、位置を抽出しようとしています。

<TABLE width="100%" align="center" cellspacing="0" cellpadding="0" border="0">

<TR>
    <TD></TD>
    <TD></TD>
    <TD align="center" nowrap colspan="3"><FONT size="2"><B>Age as of</B></FONT></TD>
    <TD></TD>
    <TD></TD>
</TR>

<TR>
    <TD align="center" nowrap><FONT size="2"><B>Name</B></FONT></TD>
    <TD></TD>
    <TD align="center" nowrap colspan="3"><FONT size="2"><B>November 1, 1999</B></FONT></TD>
    <TD></TD>
    <TD align="center" nowrap><FONT size="2"><B>Position</B></FONT></TD>
</TR>

<TR>
    <TD align="center" nowrap><HR size="1"></TD>
    <TD></TD>
    <TD align="center" nowrap colspan="3"><HR size="1"></TD>
    <TD></TD>
    <TD align="center" nowrap><HR size="1"></TD>
</TR>

<TR>
    <TD align="left" valign="top"><FONT size="2">
    Terry S. Jacobs</FONT></TD>
    <TD></TD>
    <TD></TD>
    <TD align="right" valign="top" nowrap><FONT size="2">57</FONT></TD>
    <TD></TD>
    <TD></TD>
    <TD align="left" valign="top"><FONT size="2">
    Chairman of the Board, Chief Executive Officer, Treasurer and
    director</FONT></TD>
</TR>

<TR><TD><TR><TD><TR><TD><TR><TD>

<TR>
    <TD align="left" valign="top"><FONT size="2">
    William L. Stakelin</FONT></TD>
    <TD></TD>
    <TD></TD>
    <TD align="right" valign="top" nowrap><FONT size="2">56</FONT></TD>
    <TD></TD>
    <TD></TD>
    <TD align="left" valign="top"><FONT size="2">
    President, Chief Operating Officer, Secretary and director</FONT></TD>
</TR>

<TR><TD><TR><TD><TR><TD><TR><TD>

<TR>
    <TD align="left" valign="top"><FONT size="2">
    Joel M. Fairman</FONT></TD>
    <TD></TD>
    <TD></TD>
    <TD align="right" valign="top" nowrap><FONT size="2">70</FONT></TD>
    <TD></TD>
    <TD></TD>
    <TD align="left" valign="top"><FONT size="2">
    Vice Chairman and director</FONT></TD>
</TR>

</TABLE>

私の現在の試みは次のとおりです。

    soup = BeautifulSoup(in_file)
    out = []
    headers = soup.findAll(['td','th'])
    for header in headers:
        if header.find(text = re.compile(r"^age( )?", re.I)):
            out.append(header)
    table = out[0].find_parent("table")
    rows = table.findAll('tr')
    filter_regex = re.compile(r'[\w][\w .,]*', re.I)
    data = [[td.find(text=filter_regex) for td in tr.findAll("td")] for tr in rows]

物事は一人称でうまくいきますが、悪い<tr><td><tr><td>...線は本当にそこから物事を台無しにします。それぞれがわずかに異なるテーブル構造を持つ数千のHTMLファイルに対してこれを実行しようとしています。とは言うものの、この機能<tr><td>タグが閉じられていないことは、ファイル全体で非常に一般的であるように見えます。

上記の解析を一般化して、このような構造を持つテーブルを操作する方法について考えたことがある人はいますか?どうもありがとう!

4

2 に答える 2

0

保持したいすべてのフィールドでvalign属性が設定されているという事実を利用できますが、保持したくないフィールドはどれも設定されていません。top

soup = BeautifulSoup(in_file)
cells = [cell.text.strip() for cell in soup('td', valign='top')]

次に、このセルのリストを2次元構造に並べ替えることができます。エントリごとに3つのセルがあるので、次のようにするだけでかなり簡単に分類できます。

entries = []
for i in range(0, len(cells), 3):
    entries.append(cells[i:i+3])
于 2012-07-25T02:34:32.450 に答える
0

偶然にも、他の誰かがこの問題に悩まされてここでつまずく場合、最新の解決策は、使用しているパーサーを変更することです。デフォルトのパーサーである「html.parser」は、適切に閉じられたタグを使用して十分に近いHTMLを処理する場合に非常に適していますが、2番目にエッジケース(OPの問題に類似した以下の例1など)を処理する必要があります。 8年後でもウィンドウのすぐ外に出ます(以下の例2)。

BeautifulSoup4(現在のバージョン4.9.3)のドキュメントには、パーサーの選択について詳しく説明したセクションがあります:https ://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser

例1、生のHTML:

<TABLE >
  <TR VALIGN="top">
    <td>&nbsp;<td><b>Title:</b>
    <td>&nbsp;title is here <i>-subtitle</i><br>
  <TR VALIGN="top">
    <td>&nbsp;
    <td><b>Date:</b>
    <td>&nbsp;Thursday , August 27th, 2020
  <TR VALIGN="top">
    <td>&nbsp;<td><b>Type:</b>
    <td>&nbsp;61
  <TR VALIGN="top">
    <td>&nbsp;
    <td><b>Status:</b>
    <td>&nbsp;ACTIVE - ACTIVE
</TABLE>

例2、以下を使用した場合の結果BeautifulSoup(html, 'html.parser')

<table>
<tr valign="top">
<td> <td><b>Title:</b>
<td> title is here <i>-subtitle</i><br/>
<tr valign="top">
<td>
    <td><b>Date:</b>
<td> Thursday , August 27th, 2020
  <tr valign="top">
<td> <td><b>Type:</b>
<td> 61
  <tr valign="top">
<td>
    <td><b>Status:</b>
<td> ACTIVE - ACTIVE
</td></td></td></tr></td></td></td></tr></td></td></td></tr></td></td></td></tr></table>

例3、以下を使用した場合の結果BeautifulSoup(html, 'html5lib')

<table>
  <tbody><tr valign="top">
    <td> </td><td><b>Title:</b>
    </td><td> title is here <i>-subtitle</i><br/>
  </td></tr><tr valign="top">
    <td>
    </td><td><b>Date:</b>
    </td><td> Thursday , August 27th, 2020
  </td></tr><tr valign="top">
    <td> </td><td><b>Type:</b>
    </td><td> 61
  </td></tr><tr valign="top">
    <td>
    </td><td><b>Status:</b>
    </td><td> ACTIVE - ACTIVE
</td></tr></tbody></table>

ドキュメントによると、Cで外部的に記述された「lxml」などのパーサーもあり、これを使用するとはるかに高速になります。

于 2021-03-13T10:29:55.660 に答える