18

Webサイトからテーブルデータを取得しようとしています。

簡単な例の表を次に示します。

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>'}

text=Trueのパラメータを認識していますがfindAll()、使用しても期待どおりの結果が得られません。

私はpython2.6とBeautifulSoup3を使用しています。

4

5 に答える 5

21

これを試して:

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
于 2012-08-10T12:43:10.140 に答える
7

テーブルをスクレイピングしている場合、次のような明示的な「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"}
]

PSこれはlxml.htmlを使用しています。BeautifulSoup を使用している場合は、「.text_content()」を「.string」に、「.cssselect」を「.findAll」に置き換えます。

于 2014-11-30T15:27:31.783 に答える
5

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
于 2014-11-18T16:37:04.457 に答える