有沒有簡單的方法使用Mathematica從特定的HTML表格中提取數據? Import
似乎非常強大,Mathematica似乎能夠很好地處理XML等格式。使用Mathematica從HTML中提取信息
下面是一個例子:http://en.wikipedia.org/wiki/Unemployment_by_country
有沒有簡單的方法使用Mathematica從特定的HTML表格中提取數據? Import
似乎非常強大,Mathematica似乎能夠很好地處理XML等格式。使用Mathematica從HTML中提取信息
下面是一個例子:http://en.wikipedia.org/wiki/Unemployment_by_country
對於這種普遍的例子還有這些密技:
對於這個具體的例子只是導入
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] :>
[email protected]], StringTrim[#]] & /@ tmp1[[All, 1]]]
這仍然會產生一些CountryData
不能識別的輸出。
flags = CountryData[#, "Flag"] & /@ tmp2;
Cases[flags, _CountryData]
6未命中出190.從輸出刪除那些未命中:
flags = If[Head[#] === CountryData, {""}, {#}] & /@ flags; (*much faster than rule replacement*)
tmp2 = Join[flags, tmp1, 2];
Grid[tmp2, Frame -> All]
注意這需要一段時間來呈現。
爲使用Grid
選項需要,可以很明顯的風格和Grid
也如果需要調整圖像。
關於'(*比規則替換更快*) ',這比你的代碼更快:'List/@ Replace [flags,_CountryData - >「」,1 ]'。 (+1,btw) – 2012-01-12 10:21:07
你是對的。我測試過'ReplaceAll',它很慢。 「替換」要快得多。 – 2012-01-12 11:51:18
Import[
"http://en.wikipedia.org/wiki/Unemployment_by_country",
"Data"]
當然,其結果將經常需要進一步的處理。你想如何想象它?
可以使用
Import[
"http://en.wikipedia.org/wiki/Unemployment_by_country",
"Elements"]
我會以某種方式想象它,但主要的是首先創建一個對應於表的矩陣, 。 – 2012-01-10 20:20:30
如果''Data''不起作用,那麼我會嘗試''XMLObject'',然後仔細使用'Cases'。儘管如此,這種方法很快就會變得麻煩。 – 2012-01-10 20:22:36
+1用於指出「導入[...,」元素「] [。](http://reference.wolfram.com/mathematica/ref/Import.html#405487078) – Simon 2012-01-11 09:56:19
對於 '易' 的某些價值發現所有Import
類型的,是的。請參閱:HTML Import documentation for Mathematica 8.
您可以使用"Data"
格式選項(例如, Import["file.hml", "Data"]
。這是一個開始,但你的鏈接是一個完整的DOM樹的價值表,divs和其他東西。它有文件記載,但很薄弱,你必須試驗。它確實可以與URL一起工作。
這個實際上工作。帶着幾分清洗,你可以在這裏使用的數據:
Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "Data"]
雖然使用Import
可能是一個更好,更穩健的方式,我發現,至少在這個特定的問題,我自己的HTML解析器(出版在this thread),工作良好,少量的後處理。如果你從那裏的代碼並執行它,使用此功能增強它:
Clear[findAndParseTables];
findAndParseTables[text_String] :=
Module[{parsed = [email protected][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 = [email protected][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對象),通常很容易建立一套替換規則,在每種情況下都能進行正確的後處理。最後一個免責聲明是我的解析器不健壯,確實包含許多錯誤,所以要警告。
您必須有足夠的材料才能編寫現在另一本Mathematica書。其實,我希望你能做到。 ;-) – 2012-01-11 11:27:30
@ ndroock1謝謝!我正在努力,但最近我有太多的直接工作要有足夠的空閒時間來快速完成。在SO這裏回答帖子是一回事,但寫一本認真的書需要更多的時間,至少在覈心完成之前。希望能儘快獲得更多時間。順便說一句,有一個新的Mathematica SE網站的建議:http://area51.stackexchange.com/proposals/37304/mathematica。如果你還沒有這樣做,請考慮支持它。 – 2012-01-11 11:48:03
@ ndroock1只需添加到以前的內容:該提案現在正在將它的(希望是最終的)步驟從提交階段提交到測試版。以下是不夠的,它不會自動轉入提交。 – 2012-01-11 12:03:22
如果您想要導入[...,「XMLObject」]路線,下面概述了您可以執行的操作。
首先,讓頁面:
page = Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "XMLObject"];
接下來,獲得的利息表(在這種情況下,大表也正好是第一的七個表此頁):
table = Cases[page, XMLElement["table", ___], \[Infinity]][[1]]
接下來,從table
得到row
,我挑選的第四行與對應阿爾及利亞:
行=例[表,的XMLElement [ 「TR」,___],[Infi的無窮大]] [[4]]
接着,從該行中提取表的數據元素():
data = Cases[row, XMLElement["td", ___], \[Infinity]]
缺貨那些元件的,可以挑例如國家標誌縮略圖,像這樣:
image = Cases[data, XMLElement["img", {___, "src" -> src_, ___}, _] :> src, \[Infinity]]
最後導入圖像的縮略圖(它需要的 「http:」 前面加上出於某種原因):
Import["http:" <> image]
這是筆記本電腦是什麼樣子(縮略圖,加上其它輸入):
沒有直接回答如何導入HTML(該人已很好地解釋),但獲得的數據來自HTML表格是恰恰是爲什麼我原來是我的table paste 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}}
正如你所看到的,需要一些後處理多年轉換成合適的格式
這是舊的調色板代碼。我意識到它需要清理,但它仍然可以正常工作,而且我還沒有時間來修復它。在下面的評論中報告任何問題。
[email protected]@{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[],
[email protected][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[],
[email protected][strip, ImportString[data, "CSV"], {2}]]
]
]
],
Button["Table",
Module[{data},
data = NotebookGet[ClipboardNotebook[]][[1, 1, 1]];
If[Head[data] === String,
NotebookWrite[InputNotebook[],
[email protected][data, "Table"]]
]
]
]}
這工作完美無瑕。非常便利。 – 2012-01-11 19:44:55
這很好。我希望我能理解正則表達式。它似乎很神祕:) – 2012-01-11 21:35:25
@Mike它只是一個'StringTrim'。我爲最初的Mathematica 6寫了這個,裏面沒有'StringTrim'。 – Szabolcs 2012-01-11 22:29:47
IMO,如果您使用的是版本8,JSON是要走的路。在野外有大量的API(通常以您的方式拋出XML或JSON)。我不會建議殺死時間從Wiki中翻譯失業數據。找到你感興趣的主要來源,它可能會有一個API。如果您只想快速翻閱某些內容,也可以嘗試在Excel中鏈接單元格,然後您可以導入到MMA中。 (如果你只是想玩得開心並學習,那麼忽略所有這一切,在這種情況下,解析掉):D – telefunkenvf14 2012-01-11 01:34:25