Pull to refresh

WIKIзуализируй то, WIKIзуализируй это!

Reading time 4 min
Views 1.5K
Добрый вечер Дорогие друзья!

Недавно, прогуливаясь по просторам бескрайнего интернета, я наткнулся на изумительные работы Криса Харрисона, посидев немного в шоке, я подумал «А сложно ли визуализировать википедию или нет?» и решил попробовать!

image

Итак, приступим!


Приборы и инструменты


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


Разработчики Wiki API его описали просто отлично, поэтому не стоит переводить описание дословно чтобы понять как вызвать тот или иной метод.

На хабре уже писали о пакете Graphviz, поэтому я думаю не стоит его повторно описывать. Но я сразу почитав описание языка dot и средств graphviz чуть не начал писать свое формирование .dot файлов.

Меня выручил модуль python под названием PyGraphviz, который позволяет в удобном виде работать со структурой графа, которая потом пишется в .dot файл.

Основы


Итак визуализировать мы будем перекрестные статьи из википедии. Для этого нам потребуется вызвать метод по ссылке:
ru.wikipedia.org/w/api.php?action=query&format=xml&titles=ЗАГОЛОВОК_СТАТЬИ&prop=links
где action — это тип метода, format — выходной формат ответа, в нашем случае это XML, prop — запрашиваем перекрестные сcылки links

на выходе мы получаем следующий ответ:
  1. <api>
  2.  <query>
  3.   <normalized>
  4.    <n from="хабрахабр" to="Хабрахабр"/>
  5.   </normalized>
  6.   <pages>
  7.    <page pageid="340809" ns="0" title="Хабрахабр">
  8.    <links>
  9.     <pl ns="0" title="2006"/>
  10.     <pl ns="0" title="2006 год"/>
  11.     <pl ns="0" title="2007 год"/>
  12.     <pl ns="0" title="Digg.com"/>
  13.     <pl ns="0" title="Linux.org.ru"/>
  14.     <pl ns="0" title="News 2.0"/>
  15.     <pl ns="0" title="Newsland"/>
  16.     <pl ns="0" title="Pligg"/>
  17.     <pl ns="0" title="Slashdot"/>
  18.     <pl ns="0" title="URL"/>
  19.    </links>
  20.   </page>
  21.  </pages>
  22.  </query>
  23.  <query-continue>
  24.    <links plcontinue="340809|0|Блог"/>
  25.  </query-continue>
  26. </api>
* This source code was highlighted with Source Code Highlighter.


Который обрабатывается с помощью любого способа DOM или SAX

Программирование


Итак для обработки я использовал SAX и наследовал свой класс от xml.sax.handler.ContentHandler:
class LinksListHandler(xml.sax.handler.ContentHandler):
Далее переопределяются основные вызовы:
  • startElement
  • endElement


Процедура работы с запросом имеет следующий вид:
  1. def get_links(page):
  2.   #See wiki api documentation http://en.wikipedia.org/w/api.php
  3.   query_val = { 'action': 'query',
  4.          'prop': 'links',
  5.          'titles': page,
  6.          'format': 'xml'}
  7.   url = wiki_url() + '?' + urllib.urlencode(query_val)
  8.   request = urllib2.Request(url)
  9.  
  10.   verbose_message("Wiki url: " + url)
  11.   try:
  12.     response = urllib2.urlopen(request)
  13.   except urllib2.HTTPError:
  14.     print "HTTP request error!"
  15.     sys.exit(1)
  16.   #verbose_message("Response xml:\n"+response.read())
  17.   lh = LinksListHandler()
  18.   saxparser = xml.sax.make_parser()
  19.   saxparser.setContentHandler(lh)
  20.   saxparser.parse(response)
  21.   
  22.   return lh.links
* This source code was highlighted with Source Code Highlighter.


Построение графа


С помощью модуля PyGraphviz работы производится довольно просто:
  1. def make_wiki_graph(wiki_page, depth):
  2.   gv = AGraph()
  3.   
  4.   page_list = [wiki_page]
  5.   temp_list = []
  6.  
  7.   verbose_message('Create graph for ' + wiki_page)
  8.   pageLinks = get_links(wiki_page)
  9.   gv.add_node(wiki_page)
  10.   for i in range(depth):
  11.     print '>>>> Get '+str(i)+' level'
  12.     for page in page_list:
  13.       list = get_links(page)
  14.       node = gv.get_node(page)
  15.       node.attr['fontsize'] = "%i" % (MIN_FONT*2*(depth - i))
  16.       for link in list:
  17.         verbose_message(page + "=>" + link)
  18.         gv.add_edge(page,link)
  19.         temp_list.append(link)
  20.     page_list = temp_list
  21.     temp_list = []
  22.   return gv
* This source code was highlighted with Source Code Highlighter.

Результаты


Статья «Mathematics» с 4-мя уровнями вложенности
image
Статья «Хабрахабр» с 5 уровнями вложенности
image

Другие:
Сократ
Хабрахабр 3 уровня

Другие примеры

Сам скрипт

Tags:
Hubs:
+44
Comments 36
Comments Comments 36

Articles