Подтвердить что ты не робот

Извлечение информации из HTML с помощью Mathematica

Есть ли простой способ извлечения данных из конкретных таблиц HTML с помощью Mathematica? Import кажется довольно мощным, и Mathematica, похоже, способен обрабатывать форматы, такие как XML, довольно хорошо.

Вот пример: http://en.wikipedia.org/wiki/Unemployment_by_country

4b9b3361

Ответ 1

Для общих примеров этого есть следующие способы:

Для этого конкретного примера просто импортируйте его

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]

пуристы могут возражать против последнего шага, но когда вы очищаете данные, вы просто хотите выполнить задание, и каждый сайт - это случайная перспектива. Поэтому некоторые ручные проверки и гибкость дают вам самый быстрый общий результат.

Edit

если вам нужны флаги, вы также можете получить их из CountryData. Некоторая дальнейшая очистка необходима, иначе будет много промахов. Очистка включает в себя удаление ссылки на "суверенную страну" в скобках. например "Гуам (Соединенные Штаты)" → "Гаум".

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]

Обратите внимание, что для рендеринга это занимает некоторое время.

enter image description here

Вы можете, очевидно, пометить Grid с помощью Grid опций, а также изменить размер изображений, если это необходимо.

Ответ 2

Хотя использование Import, вероятно, является лучшим и более надежным способом, я обнаружил, что, по крайней мере для этой конкретной проблемы, мой собственный HTML-парсер (опубликованный в этот поток), отлично работает с небольшим количеством последующей обработки. Если вы берете код и выполняете его, добавив его с помощью этой функции:

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), часто бывает очень легко установить набор правил замены, которые делают правильную пост-обработку в каждом конкретном случае. Окончательный отказ от ответственности заключается в том, что мой синтаксический анализатор не является надежным и наверняка содержит несколько ошибок, поэтому будьте предупреждены.

Ответ 3

Непосредственный ответ на вопрос о том, как импортировать HTML (что хорошо объяснили другие), но получение данных из таблиц HTML именно поэтому я изначально сделал таблицу пастообразная паста.

Если ваша цель - просто получить данные, это, вероятно, будет проще и быстрее, чем пытаться разобрать страницу.

Инструкции по использованию палитры

  • Оцените выражение, создающее палитру, перейдите в "Палитры" → "Установить палитру..." и сохраните ее навсегда для последующего использования (если хотите).

  • Выберите часть таблицы на веб-странице. Если вы работаете с 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"]]
      ]
     ]
    ]}

Ответ 4

Import[
  "http://en.wikipedia.org/wiki/Unemployment_by_country",
  "Data"]

Конечно, результат будет часто нуждаться в дальнейшей обработке. Как вы хотите визуализировать его?

Вы можете найти все типы Import, используя

Import[
  "http://en.wikipedia.org/wiki/Unemployment_by_country",
  "Elements"]

Ответ 5

Если вы хотите перейти по маршруту Импорт [..., "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]

Это выглядит как ноутбук (миниатюра, а также другие входы):

Mathematica graphics

Ответ 6

При определенных значениях "легко" да. См. Здесь: Документация по документу HTML для Mathematica 8.

Вы можете импортировать из таблиц с помощью параметра формата "Data", например. Import["file.hml", "Data"]. Это начало, но ваша ссылка - это целая таблица таблиц, разделов и других вещей DOM. Это задокументировано, но тонко, и вам придется экспериментировать. Однако он работает с URL-адресами.

Это действительно работает. С небольшим количеством очистки вы можете использовать данные здесь:

Import["http://en.wikipedia.org/wiki/Unemployment_by_country", "Data"]