2012-08-10 9 views
9

ウェブサイトからテーブルデータを削り取ろうとしています。ここでBeautifulSoup、HTMLテーブルの辞書

は簡単な例テーブルです:

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

結果は次のとおりです:

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


これは、これまで私の最も近いの試みです

{'<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()であることに気付いていますが、私はそれを使用すると期待した結果が得られません。

私はPython 2.6とBeautifulSoup3を使用しています。

答えて

15

これを試してみてください:

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 
3

あなたはList Comprehensionsを使用して、ビットをmvillaressと同じアプローチに従うが、それを改善することができます

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 
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"} 
] 

P.S.をこれはlxml.htmlを使用しています。 BeautifulSoupを使用している場合は、 ".text_content()"を ".string"、 ".cssselect"を ".findAll"に置き換えてください。