使用Mathematica有一种简单的方法从特定的HTML表中提取数据吗? Import
似乎非常强大,Mathematica似乎能够很好地处理XML等格式。
以下是一个示例:http://en.wikipedia.org/wiki/Unemployment_by_country
答案 0 :(得分:13)
对于这方面的一般例子,有这些如何:
对于这个具体的例子,只需导入它
tmp = Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "Data"]
使用此导入清理它是相当简单的。该表是3列,因此从其余的东西中提取它:
tmp1 = Cases[tmp, {_, _?NumberQ, _}, \[Infinity]]
您可能想要删除方括号引用(??):
tmp1[[All, 3]] = Flatten[If[StringQ[#],
StringCases[#, x__ ~~ Whitespace ~~ "[" ~~ __ :> x], #] & /@ tmp1[[All, 3]]]
Grid[tmp1, Frame -> All]
另请注意,您可以在表格中添加标题(您可能会这样做)
Grid[Join[{{"Country / Region", "Unemployment rate (%)",
"Source / date of information"}}, tmp1], Frame -> All]
纯粹主义者可能会反对最后一步,但是当你正在抓取数据时,你只想完成工作,每个网站都是个案前景。因此,一些手动检查和灵活性可以使您获得最快的整体效果。
修改强>
如果您想要标记,您也可以从CountryData
获取标记。需要进行一些进一步的清理,否则会发生很多未命中。清理涉及删除括号中对“主权国家”的引用。例如“关岛(美国)” - > “Gaum”。
tmp2 = Flatten[
If[StringMatchQ[#, __ ~~ "(" ~~ __],
StringCases[#,
z__ ~~ Shortest["(" ~~ __ ~~ ")" ~~ EndOfString] :>
StringTrim@z], StringTrim[#]] & /@ tmp1[[All, 1]]]
这仍然会产生CountryData
无法识别的输出。
flags = CountryData[#, "Flag"] & /@ tmp2;
Cases[flags, _CountryData]
在p = 6中错过了190.从输出中删除了这些未命中:
flags = If[Head[#] === CountryData, {""}, {#}] & /@ flags; (*much faster than rule replacement*)
tmp2 = Join[flags, tmp1, 2];
Grid[tmp2, Frame -> All]
请注意,渲染需要一段时间。
您可以使用Grid
选项根据需要设置Grid
的样式,并在需要时调整图片大小。
答案 1 :(得分:6)
虽然使用Import
可能是一种更好更强大的方式,但我发现,至少对于这个特定问题,我自己的HTML解析器(在this thread中发布),可以正常使用少量的后期处理。如果你从那里获取代码并执行它,用这个函数扩充它:
Clear[findAndParseTables];
findAndParseTables[text_String] :=
Module[{parsed = postProcess@parseText[text]},
DeleteCases[
Cases[parsed, _tableContainer, Infinity],
_attribContainer | _spanContainer, Infinity
] //.
{(supContainer | tdContainer | trContainer | thContainer)[x___] :> {x},
iContainer[x___] :> x,
aContainer[x_] :> x,
"\n" :> Sequence[],
divContainer[] | ulContainer[] | liContainer[] | aContainer[] :> Sequence[]}];
然后,我认为,这段代码可以得到相当完整的数据:
text = Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "Text"];
myData = First@findAndParseTables[text];
结果如下:
In[92]:= Short[myData,5]
Out[92]//Short=
tableContainer[{{Country / Region},{Unemployment rate (%)},{Source / date of information}},
{{Afghanistan},{35.0},{2008,{3}}},{{Albania},{13.49},{2010 (Q4),{4}}},
{{Algeria},{10.0},{2010 (September),{5}}},<<188>>,{{West Bank},{17.2},{2010,{43}}},
{{Yemen},{35.0},{2009 (June),{128}}},{{Zambia},{16.0},{2005,{129}}},{{Zimbabwe},{97.0},{2009}}]
我喜欢这种方法(而不是Import->XMLObject
),因为我将网页转换为Mathematica表达式,语法最少(与XML对象不同),因此通常很容易建立一组替换规则,在每个给定的情况下进行正确的后处理。最后的免责声明是我的解析器不健壮并且确实包含许多错误,因此请注意。
答案 2 :(得分:6)
不是直接回答如何导入HTML(其他人已经很好地解释过),但是从HTML表中获取数据正是为什么我最初创建table paste palette。
如果您的目标是获取数据,这可能比尝试解析页面更容易,更快。
使用调色板的说明
评估创建调色板的表达式,转到调色板 - &gt;安装Palette ...并将其永久保存以备后用(如果您愿意)。
在网页上选择表格的一部分。如果您正在使用Firefox,请按住 CTRL 以选择表格的任何矩形部分(非常有用!)复制它。
如果您使用的是Firefox或Chrome,请按调色板上的TSV
按钮将数据粘贴到当前插入点的笔记本中。我不确定其他浏览器在复制时是否也会使用标签分隔项目。
结果如下:
{{"Afghanistan", 35.`, "2008[3]"}, {"Albania", 13.49`,
"2010 (Q4)[4]"}, {"Algeria", 10.`,
"2010 (September)[5]"}, {"American Samoa (United States)", 23.8`,
"2010[3]"}, {"Andorra", 2.9`, 2009}}
正如您所看到的,需要进行一些后期处理才能将年份转换为正确的格式(字符串或整数?)
这是旧的调色板代码。我意识到它需要清理,但它按原样工作,我还没有时间修复它。在下面的评论中报告任何问题。
CreatePalette@Column@{Button["TSV",
Module[{data, strip},
data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
strip[s_String] :=
StringReplace[s, RegularExpression["^\\s*(.*?)\\s*$"] -> "$1"];
strip[e_] := e;
If[Head[data] === String,
NotebookWrite[InputNotebook[],
ToBoxes@Map[strip, ImportString[data, "TSV"], {2}]]
]
]
],
Button["CSV",
Module[{data, strip},
data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
strip[s_String] :=
StringReplace[s, RegularExpression["^\\s*(.*?)\\s*$"] -> "$1"];
strip[e_] := e;
If[Head[data] === String,
NotebookWrite[InputNotebook[],
ToBoxes@Map[strip, ImportString[data, "CSV"], {2}]]
]
]
],
Button["Table",
Module[{data},
data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
If[Head[data] === String,
NotebookWrite[InputNotebook[],
ToBoxes@ImportString[data, "Table"]]
]
]
]}
答案 3 :(得分:5)
Import[
"http://en.wikipedia.org/wiki/Unemployment_by_country",
"Data"]
当然,结果经常需要进一步处理。你想如何形象化它?
您可以使用
找到所有Import
类型
Import[
"http://en.wikipedia.org/wiki/Unemployment_by_country",
"Elements"]
答案 4 :(得分:4)
如果你想进入Import [...,“XMLObject”]路线,这里是你可以做的概述。
首先,获取页面:
page = Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "XMLObject"];
接下来,获取感兴趣的表格(在这种情况下,大表也恰好是此页面上七个表格中的第一个):
table = Cases[page, XMLElement["table", ___], \[Infinity]][[1]]
接下来,从row
获取table
,我选择了与阿尔及利亚相对应的第四行:
row = Cases [table,XMLElement [“tr”,___],[Infinity]] [[4]]
接下来,从该行中提取表数据元素():
data = Cases[row, XMLElement["td", ___], \[Infinity]]
在这些元素中,你可以选择国家标志缩略图,如下所示:
image = Cases[data, XMLElement["img", {___, "src" -> src_, ___}, _] :> src, \[Infinity]]
最后导入该图像缩略图(出于某种原因需要“http:”前缀):
Import["http:" <> image]
这就是笔记本的样子(缩略图和其他输入):
答案 5 :(得分:3)
对于'easy'的某些值,是的。见这里:HTML Import documentation for Mathematica 8.
您可以使用"Data"
格式选项从表中导入,例如Import["file.hml", "Data"]
。这是一个开始,但你的链接是一个完整的DOM树值表,div和其他东西。它是有记录的,但很薄,你必须进行实验。它确实适用于URL。
这个实际上有效。通过一些清洁,您可以使用此处的数据:
Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "Data"]