2017-07-03 79 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')