Python Beautiful Soup找不到表格

时间:2017-07-03 20:04:04

标签: python html web-scraping beautifulsoup

我有一个无法找到表的网页抓取代码。 我的代码如下:

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

但由于某种原因,我的代码总是将表返回为none。我不知道为什么,但任何帮助将不胜感激。感谢。

3 个答案:

答案 0 :(得分: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> ...

答案 1 :(得分:0)

您需要指定要解析的内容

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

然后你可以很好地验证它是否正确解析

print(soup.prettify())

答案 2 :(得分: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

  3. 首先安装它:

    # pip install html5lib

    您可以通过以下方式使用它:

    soup = BeautifulSoup(page, 'html5lib')