在主页中,旅游统计数据似乎由 JavaScript <div class="tourViewData"> ... populateDDs(); 填充
BS 不解析 Javascript,请参阅许多其他 SO 问题。
(我不知道如何解决该部分。最坏的情况是,选择该 HTML 选择并将其保存为本地 html 文件,作为一种解决方法。)
首先,将 s 设置为该 URL 的 BeautifulSoup 对象(我使用斜纹而不是原始机械化,将您的机械化等效物放在这里):
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 中删除逗号。