如何从没有很多结构的抓取页面中提取数据

时间:2013-10-23 03:44:41

标签: python html web-scraping lxml

我想对我刚刚在棒球统计网站上阅读的帖子做一些分析。有问题的页面位于http://www.fangraphs.com/blogs/fangraphs-crowd-the-top-47-free-agents/

我想抓取以玩家姓名下方的段落标签中的玩家姓名开头的数据(块图像显示他们在列表中的#)。 (所以不是下面的表数据。)

数据的一个例子:

#1 Robinson Cano (2B) 
Age PA  BB%     K%       AVG    OBP      SLG    wOBA    wRC+    Off  Def    WAR
30  681 9.5%    12.5%   .314    .383    .516    .384    142     30.6 2.5    6.0

Real Years: 8
Real AAV: $24.5
Real Total: $196.2

Fake Years: 5
Fake AAV: $23.9
Fake Total: $119.7

Representative Comment
“I wouldn’t want to guarantee salary past age 37 or age 38. I could see him getting more years than that, at the same AAV I am willing to pay in fake world.”

[next player in example]...
#2 Jacoby Ellsbury
[etc.]

编号项目(#1)不在OL中,但在a标签上确实有一个name属性。所以我可以抓住它。不幸的是,其余的数据似乎并没有在html中以易于理解的方式构建。

我希望通过“假总额:119.7美元”提取“真实年份:8”的数据。 (注意:其他一些玩家有不同的数据键,例如“将接受合格的报价”。我知道所有这些键都是什么,但不是每个玩家都有每个数据输入。)

我的策略是选择列表中的第一个玩家,并从那里开始抓取兄弟元素。如果兄弟元素的文本与我的一个已知键(“Real Years”等)相匹配,则存储该值的数值。如果兄弟元素是具有name属性的<a>元素,那么我知道它是下一个播放器并进入循环的下一次迭代。

我很好奇其他人会如何解决这个问题。我觉得我的方式很笨重,但这是我能想象的唯一方法,没有更多html结构的页面。

我正在使用python和lxml.html模块。

1 个答案:

答案 0 :(得分:2)

听起来这是一次性的工作,并且html的格式化不是很好,所以你不应该花太多精力为这个网页编写完美的解析器。快速而肮脏是要走的路。

更简单的解决方案是简单地复制页面文本,将其粘贴到您选择的文本编辑器中,并将其另存为纯文本文件。然后,您可以编写一个脚本来解析文本文件。

查找以“#”开头的行。这表示新玩家的部分开始。然后消耗这些线,直到下一个玩家的部分开始。