难以用美丽的汤刮桌子4

时间:2018-10-05 06:18:10

标签: python beautifulsoup

我正在尝试从中提取最常见的击球顺序 http://www.baseball-reference.com/teams/SFG/2017-batting-orders.shtml

import bs4
import urllib.request as urllib

url = 'http://www.baseball-reference.com/teams/SFG/2017-batting-orders.shtml'
html = urllib.urlopen(url).read() 
batting_order_soup = bs4.BeautifulSoup(html, "html.parser")
table = batting_order_soup.find("table", attrs={"class":"stats_table nav_table"})

>>> print(table)
None

我希望看到有6个游戏,4个游戏,4个游戏,3个游戏和2个游戏的表格。在“ 6个游戏”列下的Span,Nunez,Belt等。

在浏览器中,我在注释和html中都看到了6个游戏。

<table class="stats_table nav_table" id="st_0"><tbody><tr class="rowSum">
<td valign="top"><strong>6 Games</strong><p></p><li value="1">
 <a data-entry-id="spande01" href="/players/s/spande01.shtml" 
title="Denard Span">Span</a> </li>
<li value="2"><a data-entry-id="nunezed02" href="/players/n/nunezed02.shtml"
title="Eduardo Nunez">Nunez</a></li>

beautifulsoup中是否有一种方法可以提取表?我确实在batting_order_soup(即包含no-js的print(batting_order_soup))中看到了,所以如下面的注释所述,JavaScript无法运行。我想我们不能让bs4运行js吗?示例如何提取嵌入在注释中的表?

下面的代码可以交互运行。因此,如果您要说奔跑

table = batting_order_soup.find("table")
print(table)

您将获得第一个表格数据,即击球顺序。

谢谢你, -拉伊

1 个答案:

答案 0 :(得分:0)

因此,这里的问题是您感兴趣的标签是注释。数据在加载到浏览器中时存在,但是在您使用Python拉出时存在-例如无需加载Javascript等-只是注释。

因此,获取IMHO数据的简单方法实际上是提取所有注释(看看this answer),然后找到正确的注释,创建一个新的BeautifulSoup对象,然后解析该注释。

因此该解决方案的有效代码如下:

import requests
from bs4 import BeautifulSoup, Comment
from pprint import pprint

r = requests.get("http://www.baseball-reference.com/teams/SFG/2017-batting-orders.shtml")
soup = BeautifulSoup(r.text, "html.parser")
comments = soup.find_all(string=lambda text:isinstance(text,Comment))

# the element we need has the sentence 'stats_table nav_table' in it
for comment in comments:
    if 'stats_table nav_table' in comment:
        table_soup = BeautifulSoup(comment, "html.parser")

table = table_soup.find('table')
tds = table.find_all('td')
return_dict = {}

for td in tds:
    header = td.find('strong').get_text()
    batter_list = td.find_all('li')
    batter_list = [batter.get_text() for batter in batter_list]
    return_dict[header] = batter_list

pprint(return_dict)