Как получить результат сложного шаблона Википедии? - PullRequest
2 голосов
/ 20 января 2012

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

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", которое вы можете отправить фрагментом, подобным приведенному выше, и вы получите результаты, возвращенные так, как их увидит пользователь.Я использую это для нескольких шаблонов, и это работает, но, к сожалению, не для шаблона автоматического таксобокса.Нажмите на эту ссылку, чтобы увидеть, что возвращает expandtemplates:

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

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

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

Ответы [ 3 ]

3 голосов
/ 20 января 2012

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

2 голосов
/ 20 января 2012

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

0 голосов
/ 20 сентября 2015

Это фрагмент рабочего кода синтаксического анализа 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)
        {

        }
...