2011-01-25 161 views
2

#####更新######:renderContents()而不是內容[0]做了訣竅。如果有人能夠提供更好,更優雅的解決方案,我仍會保持開放!BeautifulSoup(Python)和解析HTML表格

我想解析一些網頁的所需數據。該表沒有類/標籤。所以我必須在tr內容中搜索'網站'。

手頭上的問題: 顯示td.contents工作正常,只是因爲文本,但由於某種原因沒有超鏈接?我究竟做錯了什麼?有沒有更好的方式在Python中使用bs來做到這一點?

那些暗示lxml,我有一個正在進行的線程here沒有管理員權限的centOS和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] 
+0

應該是(即是否缺少`>`?) – unutbu 2011-01-25 18:12:46

+0

更新了HTML,遺漏了>,仍然沒有。 – ThinkCode 2011-01-25 19:02:10

回答

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>', ''] 

於是摘列表的第一要素,使你錯過了<a> - 標籤。

1

我回答了類似的問題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        ', 
''] 
+0

感謝您的鏈接,但我有問題解析表,而不僅僅是錨標籤。在這種情況下,其中一個td內容是一個URL,我想抓住標籤中包含的所有內容。 – ThinkCode 2011-01-25 19:04:33