2017-07-03 78 views
2

我有一個網絡抓取代碼,無法找到表。 我的代碼如下所示:Python美麗的湯找不到表

site = 'http://etfdb.com/compare/market-cap/' 
hdr = {'User-Agent': 'Mozilla/5.0'} 
req = Request(site, headers=hdr) 
page = urlopen(req) 
soup = BeautifulSoup(page) 
table = soup.find('table', {"class":"table mm-mobile-table table-striped 
table-bordered"}) 

的表格HTML看起來像:

<table class="table mm-mobile-table table-striped table-bordered" data- 
icons-prefix="fa" data-icons="{&quot;columns&quot;:&quot;fa-th&quot;}" data- 
striped="true" data-toggle="table"> 

但由於某種原因我的代碼總是返回表爲無。我不知道爲什麼,但任何幫助將不勝感激。謝謝。

+0

有在'soup'沒有表(也不在'page')。服務器可能不會將'Mozilla/5.0'識別爲有效的代理。 – DyZ

回答

3

的問題是,有不正確的標記使註釋掉的代碼的大段即

<!-->. 

修復被替換這些元素然後解析HTML。

from urllib2 import urlopen, Request 
from bs4 import BeautifulSoup 
site = 'http://etfdb.com/compare/market-cap/' 
hdr = {'User-Agent': 'Mozilla/5.0'} 
req = Request(site, headers=hdr) 
res = urlopen(req) 
rawpage = res.read() 
page = rawpage.replace("<!-->", "") 
soup = BeautifulSoup(page, "html.parser") 
table = soup.find("table", {"class":"table mm-mobile-table table-striped table-bordered"}) 
print (table) 

測試Python的2.7.12

from urllib.request import urlopen, Request 
from bs4 import BeautifulSoup 
site = 'http://etfdb.com/compare/market-cap/' 
hdr = {'User-Agent': 'Mozilla/5.0'} 
req = Request(site, headers=hdr) 
res = urlopen(req) 
rawpage = res.read().decode("utf-8") 
page = rawpage.replace('<!-->', '') 
soup = BeautifulSoup(page, "html.parser") 
table = soup.find("table", {"class":"table mm-mobile-table table-striped table-bordered"}) 
print (table) 

測試上的Python 3.5。2

給出:

<table class="table mm-mobile-table table-striped table-bordered" data-icons='{"columns":"fa-th"}' data-icons-prefix="fa" data-striped="true" data-toggle="table"><thead><tr><th class="show-td" data-field="symbol">Symbol</th> <th class="show-td" data-field="name">Name</th> <th class="show-td" data-field="aum">AUM</th> <th class="show-td" data-field="avg-volume">Avg Volume</th></tr></thead><tbody><tr><td class="show-td" data-th="Symbol"><a href="/etf/SPY/">SPY</a></td> <td class="show-td" data-th="Name"><a href="/etf/SPY/">SPDR S&amp;P 500 ETF</a></td> <td class="show-td" data-th="AUM">$236,737,519.17</td> <td class="show-td" data-th="Avg Volume">73,039,883</td></tr> <tr><td class="show-td" data-th="Symbol"><a href="/etf/IVV/">IVV</a></td> <td class="show-td" data-th="Name"><a href="/etf/IVV/">iShares Core S&amp;P 500 ETF</a></td> <td class="show-td" data-th="AUM">$115,791,603.10</td> <td class="show-td" data-th="Avg Volume">3,502,931</td></tr> ... 
+0

這一個工作。謝謝! – Bruno

0

你需要指定你想要什麼解析

soup = BeautifulSoup(page, 'html.parser') 

然後你就可以很好的驗證它是否解析正確

print(soup.prettify()) 
0

我不知道也許是因爲他們的代碼是不是結構良好[故意],BeautifulSoup無法解析它。但是,也許這可以幫助您:

import re # to extract table with regex 
table_soup = BeautifulSoup(re.findall(r'<table.*>.*</table>', page.read())[0]) 

您也可以進一步與這樣的調查:

for tag in soup.find_all(): 
    if tag.name == 'div': 
     if str(tag).find("table-striped") > -1: 
     print repr(str(tag)[:100]) 

要查看哪些div標籤包含table,如果有的話:

'<div class="mm-header">\n<div class="container">\n<div class="row">\n<div class="col-xs-12">\n<div class' 
'<div class="container">\n<div class="row">\n<div class="col-xs-12">\n<div class="mm-user-links hidden-x' 
'<div class="row mm-header-content">\n<div class="col-sm-4 mm-header-logos">\n<button class="navbar-tog' 
'<div class="col-sm-4 mm-header-logos">\n<button class="navbar-toggle">\n<span class="fa fa-bars"></spa' 

所以我猜BeautifulSoup不能將最後一個分解成子標籤。

編輯:

  1. 對不起,我忘了添加page.read()先獲取頁面的源代碼,再看到第二行。

  2. 如果你不想使用正則表達式,你可以使用更好的解析器而不是默認的一個:html5lib

首先安裝:

# pip install html5lib

您可以使用它:

soup = BeautifulSoup(page, 'html5lib')