Парсинг Wikipedia

Недавно с удивлением узнал о том, что Wikipedia – это не только ценный мех отличный источник информации, но еще и очень приличное API для доступа к этой самой отличной информации. Ну а там, где есть какое-то API, почти наверняка найдется Python библиотека к нему.

А вообще, затеял я все это дело ради того, что бы загрузить список языков программирования с Wikipedia и получить немного дополнительной информации по ним. Что удивительно, полностью подходящей мне библиотеки не нашлось, и пришлось писать небольшой патчик к библиотеки Wikipedia, благо на Python код пишется очень быстро. В примерах используется та версия, что лежит у меня на GitHub. Это вызвано тем, что мои изменения в основном репозитории библиотеки Wikipedia несколько видоизменили и теперь результат новых функций выглядит более читабельным, но бесполезным в моем случае, т.к. возвращает отформатированный текст, а не Markdown.

Да, а кроме того, я решил проверить на сколько удобно использовать IPython Notebook для написания постов в WordPress %-)

In [28]:
import wikipedia
import re

Для начала нужно получить список секций с типами языков программирования:

In [29]:
langs = wikipedia.page("List_of_programming_languages_by_type")
langs.sections[:10]
Out[29]:
[{'index': u'1', 'title': u'Array language'},
 {'index': u'2', 'title': u'Aspect-oriented languages'},
 {'index': u'3', 'title': u'Assembly languages'},
 {'index': u'4', 'title': u'Authoring languages'},
 {'index': u'5', 'title': u'Command line interface languages'},
 {'index': u'6', 'title': u'Compiled languages'},
 {'index': u'7', 'title': u'Concurrent languages'},
 {'index': u'8', 'title': u'Curly-bracket languages'},
 {'index': u'9', 'title': u'Dataflow languages'},
 {'index': u'10', 'title': u'Data-oriented languages'}]

И добавить немного магии с регулярками. Основная идея следующая: информация о языках хранится в виде “* [[линк_на_статью_в_вики | название_языка ]] какое-то текстовое описание”

In [30]:
def process_type(section):
    result = []
    lines = section.split('\n')
    for line in lines:
        # * [[wiki_link | lang_name]]
        lang = re.search('^\*+\s*(\[\[' # * or ** and [[
                        '((?P<wiki_link>[^\[]*?)(\|))?' #optional wiki_link using lazy algorithm
                         '(?P<lang_name>.+?)' 
                         '\]\])', line) # ]]
        if lang:
            result.append(lang.groupdict())
    return result

И заключительный штрих – собрать в кучу всю загруженую информацию.

In [31]:
langs_info = {}
for section in langs.sections:
    section_data = langs.section(section['index'])
    lang_list = process_type(section_data)
    langs_info[section['title']] = lang_list
In [32]:
print langs_info.keys()
[u'Concurrent languages', u'Iterative languages', u'Declarative languages', u'In object code', u'Interpreted languages', u'Dataflow languages', u'HDLs for digital circuit design', u'Multiparadigm languages', u'Little languages', u'Data-structured languages', u'Fourth-generation languages', u'Wirth languages', u'Server side', u'Pure', u'Syntax handling languages', u'Hardware description languages', u'See also', u'Data-oriented languages', u'Scripting languages', u'XML-based languages', u'Functional languages', u'Command line interface languages', u'In source code', u'Imperative languages', u'Aspect-oriented languages', u'Single dispatch', u'Authoring languages', u'Procedural languages', u'Non-English-based languages', u'Assembly languages', u'Reflective languages', u'Stack-based languages', u'Object-oriented class-based languages', u'Visual languages', u'Extension languages', u'Logic-based languages', u'Application macro languages', u'Client side', u'Macro languages', u'List-based languages \u2013 LISPs', u'Embeddable languages', u'Numerical analysis', u'Esoteric languages', u'Rule-based languages', u'Impure', u'External links', u'Textual substitution macro languages', u'Synchronous languages', u'Multiple dispatch', u'Object-oriented prototype-based languages', u'Array language', u'Compiled languages', u'Educational languages', u'Metaprogramming languages', u'HDLs for analog circuit design', u'Off-side rule languages', u'Interactive mode languages', u'Machine languages', u'References', u'Curly-bracket languages']
In [33]:
print langs_info[langs_info.keys()[1]]
[{'wiki_link': None, 'lang_name': u'Aldor'}, {'wiki_link': u'Alphard (programming language)', 'lang_name': u'Alphard'}, {'wiki_link': u'Generator (computer science)#C#', 'lang_name': u'C#'}, {'wiki_link': u'CLU (programming language)', 'lang_name': u'CLU'}, {'wiki_link': u'Cobra (programming language)', 'lang_name': u'Cobra'}, {'wiki_link': u'Eiffel (programming language)', 'lang_name': u'Eiffel'}, {'wiki_link': u'Icon (programming language)', 'lang_name': u'Icon'}, {'wiki_link': u'Information Processing Language', 'lang_name': u'IPL-v'}, {'wiki_link': u'Lua (programming language)', 'lang_name': u'Lua'}, {'wiki_link': u'Lush (programming language)', 'lang_name': u'Lush'}, {'wiki_link': u'Python (programming language)', 'lang_name': u'Python'}, {'wiki_link': None, 'lang_name': u'Sather'}, {'wiki_link': u'XL (programming language)', 'lang_name': u'XL'}]

Вышло все неожиданно быстро и просто. Люблю Python все больше и больше

P.S. а вот IPython Notebook для написания постов как-то не очень подходит, слишком уж стили едут и текст не редактируемый становится.

 

2 Comments Парсинг Wikipedia

  1. Андрей

    По ЯП есть progopedia.ru, но там без api. Но список яп там должен быть длинее

    Reply

Leave a Reply