Как получить результат сложного шаблона Википедии?

Это вопрос, который немного сложно выполнить, но я сделаю все возможное, чтобы объяснить это. Во-первых, позвольте мне привести примерную страницу:

http://en.wikipedia.org/wiki/African_bush_elephant

Это страница википедии, специальная страница, в частности, поскольку она имеет «таксобокс» справа. Я пытаюсь проанализировать атрибуты в этом taxobox с помощью PHP. В Википедии есть два способа создать такой таксобокс: вручную или с помощью специального шаблона «auto taxobox».

Я могу разобрать ручную. Я использую API Википедии, чтобы вернуть содержимое страницы в json-формате, затем я использую некоторые регулярные выражения для получения этих свойств.

Однако в случае автоматического таксобокса возвращаемый контент выглядит следующим образом:

> {{automatic taxobox | name = African Bush Elephant<ref > name=MSW3>{{MSW3 Proboscidea | id = 11500009 | page = > 91}}</ref> | status = VU | status_system = iucn3.1 | status_ref > = <ref name=IUCN>{{IUCN2010|assessors=Blanc, J.|year=2008|version=2010.1|id=12392|title=Loxodonta > africana|downloaded=04 April 2010}}</ref> | trend = unknown | > image = African Bush Elephant.jpg | taxon = Loxodonta africana | > synonyms = ''Loxodonta africana africana'' | binomial = ''Loxodonta > africana'' | binomial_authority = ([[Johann Friedrich > Blumenbach|Blumenbach]], 1797) }} 

Если вы сравните это с фактической страницей, как видите в Википедии, вы заметите, что отсутствуют некоторые атрибуты. Например, свойство «Царство» отображается на реальной странице, но не возвращается здесь. Там больше недостающих свойств.

Это похоже на шаблон, требующий команды сервера Википедии, чтобы преобразовать шаблон в фактический вывод. Я узнал, что API имеет действие «expandtemplates», которое вы можете отправить фрагмент, подобный приведенному выше, и вы получите результаты, которые будут отображены пользователем. Я использую это для нескольких шаблонов, и это работает, но, к сожалению, не для шаблона auto taxobox. Нажмите эту ссылку, чтобы узнать, что возвращает expandtemplates:

полная ссылка

Как вы можете видеть, шаблон фактически не расширяется. Вместо этого он отображает больше шаблонов, вложенных и повторяемых несколько раз.

Итак, теперь я застреваю, пытаясь прочитать эти свойства со страниц, на которых есть шаблон auto taxobox. Единственное другое направление, о котором я могу думать, это не использовать API и просто анализировать html фактической страницы. Это может быть выполнено для некоторых свойств, но другие чрезвычайно хрупки для синтаксического анализа.

    Используйте action=parse вместо action=expandtemplates . Как вы заметили, expandtemplates только расширяет один уровень; кроме того, он не будет полностью препроцессорным вводом (например, он не будет успешно обрабатывать определенные ссылки переменных внутри шаблонов).

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

    Это фрагмент рабочего кода анализа php-шаблонов.

    Цель состоит в том, чтобы иметь массив ($ data), который выглядит так:

    $ data [page name] = array (key1 => val1, key2 => val2 …);

      $namespaceNames = ""; $data = array(); $sql_conn = array(); $query = "select * from templatelinks left join page on templatelinks.tl_from=page.page_id where tl_title='speciesbox' order by page_title;"; $sql_conn = mysql_connect('localhost', 'root', 'password'); mysql_select_db('my_wiki'); $result = mysql_query($query, $sql_conn); while($row = mysql_fetch_object($result)) { $q2 = "select rev_text_id from revision where rev_page=".$row->page_id." order by rev_timestamp desc limit 1"; if(($res2 = mysql_query($q2)) && ($row2 = mysql_fetch_object($res2))) { $q3 = "select * from text where old_id=".$row2->rev_text_id; if(($res3 = mysql_query($q3)) && ($row3 = mysql_fetch_object($res3))) { preg_match_all('/\{\{(?:[^{}]|(?R))*}}/', $row3->old_text, $info); $kvs = explode( "|", substr($info[0][0], 0, strlen($info[0][0])-2)); $item = array(); foreach($kvs as $kv) { $kv = trim($kv); if($kv == "") continue; $eq = strpos($kv, "="); if($eq === false) continue; $key = trim(substr($kv, 0, $eq)); $val = trim(substr($kv, $eq+1)); $item[$key] = $val; } if(sizeof($item) > 0) { $title = str_replace("_", " ", $row->page_title); $data[$title] = $item; } } } } foreach($data as $page=>$item) { }