如何使用Python,BeautiflSoup提取webdata并从表中进行机械化

时间:2011-08-15 23:57:28

标签: python beautifulsoup mechanize

我想从此网站上的表格中提取数据:http://www.pgatour.com/r/stats/info/xm.html?101 然后将其保存为.csv并将其带入iWorks Numbers表。 我一直在尝试使用Python,BeautifulSoup和机械化。通过查看其他示例,我一直在不知情地尝试,但没有成功。我走到这一步:

from BeautifulSoup import BeautifulSoup, SoupStrainer
from mechanize import Browser
import re
br = Browser()
response = br.open("http://www.pgatour.com/r/stats/info/xm.html?101").read()

然后我用firebug查看代码,我猜我需要解析<tbody></tbody>之间的数据。但我不知道该怎么做。 任何帮助非常感谢。

1 个答案:

答案 0 :(得分:4)

在主页面中,游览统计信息似乎由JavaScript <div class="tourViewData"> ... populateDDs();填充 BS不解析Javascript,请参阅其他许多SO问题。 (我不知道如何解决这个问题。最糟糕的是,选择并保存HTML选择作为本地html文件,作为解决方法。)

首先,将s设置为该URL的BeautifulSoup对象(我使用twill而不是raw mechanize,将你的机械等效放在这里):

from BeautifulSoup import BeautifulSoup, SoupStrainer
#from mechanize import Browser
from twill.commands import *
import re

go("http://www.pgatour.com/r/stats/info/xm.html?101")
s = BeautifulSoup(get_browser().get_html())

无论如何,您要查找的统计信息表是标有<tbody><tr class="tourStatTournHead">的表格。 只是为了使事情有点古怪,其行中的标记属性交替定义为<tr class="tourStatTournCellAlt"<tr class=""...。 我们应该搜索第一个<tr class="tourStatTournCellAlt",然后在表格中处理每个<tr>,但标题行(<tr class="tourStatTournHead">)除外。

遍历行:

tbl = s.find('table', {'class':'tourStatTournTbl'})

def extract_text(ix,tg):
    if ix==2: # player name field, may be hierarchical
        tg = tg.findChildren()[0] if (len(tg.findChildren())>0) else tg
    return tg.text.encode()

for rec in tbl.findAll('tr'): # {'class':'tourStatTournCellAlt'}):
    # Skip header rows
    if (u'tourStatTournHead' in rec.attrs[0]):
        continue        
    # Extract all fields
    (rank_tw,rank_lw,player,rounds,avg,tot_dist,tot_drives) = \
        [extract_text(i,t) for (i,t) in enumerate(rec.findChildren(recursive=False))]
    # ... do stuff

我们为玩家名称添加辅助功能(如果其中嵌入了Titleist徽标,则可能是分层的,也可能不是分层的。) 可能你想将大多数字段转换为int(),除了player(string)和avg(float);如果是这样,请记住从排名字段中删除可选的“T”(用于绑定),并从tot_dist中删除逗号。