Дерево синтаксического анализа HTML с использованием Python 2.7

Я пытался настроить одно дерево синтаксического анализа для приведенной ниже HTML-таблицы, но не смог его сформировать. Я хочу посмотреть, как выглядит древовидная структура! Кто-нибудь может мне помочь?

# <html>
#  <head>
#   <title>
#    The Dormouse's story
#   </title>
#  </head>
#  <body>
#   <p class="title">
#    <b>
#     The Dormouse's story
#    </b>
#   </p>
#   <p class="story">
#    Once upon a time there were three little sisters; and their names were
#    <a class="sister" href="http://example.com/elsie" id="link1">
#     Elsie
#    </a>
#    ,
#    <a class="sister" href="http://example.com/lacie" id="link2">
#     Lacie
#    </a>
#    and
#    <a class="sister" href="http://example.com/tillie" id="link2">
#     Tillie
#    </a>
#    ; and they lived at the bottom of a well.
#   </p>
#   <p class="story">
#    ...
#   </p>
#  </body>
# </html>

ИЗМЕНИТЬ

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\matt>easy_install ete2
Searching for ete2
Reading http://pypi.python.org/simple/ete2/
Reading http://ete.cgenomics.org
Reading http://ete.cgenomics.org/releases/ete2/
Reading http://ete.cgenomics.org/releases/ete2
Best match: ete2 2.1rev539
Downloading http://ete.cgenomics.org/releases/ete2/ete2-2.1rev539.tar.gz
Processing ete2-2.1rev539.tar.gz
Running ete2-2.1rev539\setup.py -q bdist_egg --dist-dir c:\users\arupra~1\appdat
a\local\temp\easy_install-sypg3x\ete2-2.1rev539\egg-dist-tmp-zemohm

Installing ETE (A python Environment for Tree Exploration).

Checking dependencies...
numpy cannot be found in your python installation.
Numpy is required for the ArrayTable and ClusterTree classes.
MySQLdb cannot be found in your python installation.
MySQLdb is required for the PhylomeDB access API.
PyQt4 cannot be found in your python installation.
PyQt4 is required for tree visualization and image rendering.
lxml cannot be found in your python installation.
lxml is required from Nexml and Phyloxml support.

However, you can still install ETE without such functionality.
Do you want to continue with the installation anyway? [y,n]y
Your installation ID is: d33ba3b425728e95c47cdd98acda202f
warning: no files found matching '*' under directory '.'
warning: no files found matching '*.*' under directory '.'
warning: manifest_maker: MANIFEST.in, line 4: path 'doc/ete_guide/' cannot end w
ith '/'

warning: manifest_maker: MANIFEST.in, line 5: path 'doc/' cannot end with '/'

warning: no previously-included files matching '*.pyc' found under directory '.'

zip_safe flag not set; analyzing archive contents...
Adding ete2 2.1rev539 to easy-install.pth file
Installing ete2 script to C:\Python27\Scripts

Installed c:\python27\lib\site-packages\ete2-2.1rev539-py2.7.egg
Processing dependencies for ete2
Finished processing dependencies for ete2

person Arup Rakshit    schedule 05.01.2013    source источник
comment
@Oded, я думаю, с питоном :)   -  person allergic    schedule 05.01.2013
comment
@Oded Я просто хочу посмотреть, как выглядит его древовидная структура. В основном я использую пакет python, где он обрабатывает html doc как дерево синтаксического анализа. Поэтому я хочу увидеть его древовидную структуру. Так что, если вы поможете за то же самое, я был бы полезен!   -  person Arup Rakshit    schedule 05.01.2013
comment
Я не могу, так как я не парень с питоном (теперь вы теперь понимаете, почему вы должны пометить вопрос языком). Мне тоже непонятно, как вы хотите видеть дерево синтаксического анализа - вам тоже нужно расширить его.   -  person Oded    schedule 05.01.2013
comment
@Oded Просто хочу посмотреть, как это выглядит в tree like structure? это оно. не нужно быть в питоне, как дерево. python также производит его стандартным способом. Это должно быть дерево синтаксического анализа сверху вниз   -  person Arup Rakshit    schedule 05.01.2013
comment
Почему бы не отредактировать вопрос и добавить в него эти детали?   -  person Oded    schedule 05.01.2013
comment
Я думал, что уже объяснил - я не знаю python. Кто-то еще, кто делает, может быть в состоянии помочь. Но вам действительно следует отредактировать вопрос, чтобы получить всю необходимую информацию.   -  person Oded    schedule 05.01.2013
comment
Вам нужна проанализированная структура данных дерева или визуализация дерева?   -  person vivek    schedule 06.01.2013
comment
@vivek Я хочу визуализировать дерево.   -  person Arup Rakshit    schedule 06.01.2013


Ответы (2)


Этот ответ немного запоздал, но все же я хотел бы им поделиться: введите здесь описание изображения

Я использовал networkx и lxml (который, как я обнаружил, обеспечивает более элегантный обход дерева DOM). Однако древовидная структура зависит от graphviz и pygraphviz установлен. Сам networkx просто каким-то образом распределит узлы на холсте. Код на самом деле длиннее, чем требуется, потому что я сам рисую метки, чтобы поместить их в коробку (networkx обеспечивает рисование меток, но не передает ключевое слово bbox в matplotlib).

import networkx as nx
from lxml import html
import matplotlib.pyplot as plt
from networkx.drawing.nx_agraph import graphviz_layout

raw = "...your raw html"

def traverse(parent, graph, labels):
    labels[parent] = parent.tag
    for node in parent.getchildren():
        graph.add_edge(parent, node)
        traverse(node, graph, labels)

G = nx.DiGraph()
labels = {}     # needed to map from node to tag
html_tag = html.document_fromstring(raw)
traverse(html_tag, G, labels)

pos = graphviz_layout(G, prog='dot')

label_props = {'size': 16,
               'color': 'black',
               'weight': 'bold',
               'horizontalalignment': 'center',
               'verticalalignment': 'center',
               'clip_on': True}
bbox_props = {'boxstyle': "round, pad=0.2",
              'fc': "grey",
              'ec': "b",
              'lw': 1.5}

nx.draw_networkx_edges(G, pos, arrows=True)
ax = plt.gca()

for node, label in labels.items():
        x, y = pos[node]
        ax.text(x, y, label,
                bbox=bbox_props,
                **label_props)

ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
plt.show()

Изменения в коде, если вы предпочитаете (или хотите) использовать BeautifulSoup:

Я не эксперт... только что посмотрел на BS4 в первый раз,... но он работает:

#from lxml import html
from bs4 import BeautifulSoup
from bs4.element import NavigableString

...

def traverse(parent, graph, labels):
    labels[hash(parent)] = parent.name
    for node in parent.children:
        if isinstance(node, NavigableString):
            continue
        graph.add_edge(hash(parent), hash(node))
        traverse(node, graph, labels)

...

#html_tag = html.document_fromstring(raw)
soup = BeautifulSoup(raw)
html_tag = next(soup.children)

...
person Theodros Zelleke    schedule 06.01.2013
comment
какие python packages мне нужно установить и могу ли я использовать easy_install для того же? - person Arup Rakshit; 06.01.2013
comment
вам нужны networkx, matplotlib, graphviz, pygraphviz, lxml. Я легко установил их все из менеджера пакетов в Ubuntu 12.10. - person Theodros Zelleke; 06.01.2013
comment
Вы можете загрузить graphviz в виде бинарного файла для Windows - я только что проверил это. Но lxml вам придется собирать из исходников и предоставлять необходимые зависимости (libxml2, libxslt). Сборка из исходников и связывание по своей сути сложны для Windows... Так что, честно говоря, я бы посоветовал вам пропустить lxml. Это просто необходимо здесь для синтаксического анализа и обхода HTML. Вместо этого вы можете использовать beatfulsoup. Остальные должны быть доступны через pip install или easy_install. Вам также понадобится numpy. - person Theodros Zelleke; 07.01.2013
comment
Да, BS4 я уже установил. Итак, какие-либо изменения в коде необходимы для того же? - person Arup Rakshit; 07.01.2013
comment
Ну да, def traverse(...) нужно изменить, чтобы использовать BS4-API. Я могу посмотреть на это, но я не использовал его до сих пор... - person Theodros Zelleke; 07.01.2013
comment
Хорошо, пожалуйста, помогите мне здесь, я тоже никогда не использовал этот язык программирования. впервые для меня. Так что, если вы дадите полный код, принимая вашу концепцию, я смогу двигаться вперед! ваша помощь есть и всегда будет для меня чем-то вроде god gift! :) - person Arup Rakshit; 07.01.2013
comment
@PythonLikeYOU Я обновил свой ответ, чтобы он работал с BS4. - person Theodros Zelleke; 07.01.2013
comment
Спасибо за ваше время, но не знаете, как использовать первый и второй вместе? - person Arup Rakshit; 07.01.2013

Модули Python:
1. ETE, но для этого требуется данные в формате Newick.
2. GraphViz + pydot. См. этот ответ SO.

Javascript:
Удивительный d3 TreeLayout, использующий формат JSON.

Если вы используете ETE, вам нужно преобразовать html в формат newick. Вот небольшой пример, который я сделал:

from lxml import html
from urllib import urlopen


def getStringFromNode(node):
    # Customize this according to
    # your requirements.
    node_string = node.tag
    if node.get('id'):
        node_string += '-' + node.get('id')
    if node.get('class'):
        node_string += '-' + node.get('class')
    return node_string


def xmlToNewick(node):
    node_string = getStringFromNode(node)
    nwk_children = []
    for child in node.iterchildren():
        nwk_children.append(xmlToNewick(child))
    if nwk_children:
        return "(%s)%s" % (','.join(nwk_children), node_string)
    else:
        return node_string


def main():
    html_page = html.fromstring(urlopen('http://www.google.co.in').read())
    newick_page = xmlToNewick(html_page)
    return newick_page

main()

Вывод (http://www.google.co.in в < em>ньюик формат):

'((meta,title,script,style,style,script)head,(script,textarea-csi,(((b-gb1,a-gb1,a-gb1,a-gb1,a-gb1,a-gb1,a-gb1,a-gb1,(u)a-gb1)nobr)div-gbar,((span-gbn-gbi,span-gbf-gbf,span-gbe,a-gb4,a-gb4,a-gb_70-gb4)nobr)div-guser,div-gbh,div-gbh)div-mngb,(br-lgpd,(((div)div-hplogo)div,br)div-lga,(((td,(input,input,input,(input-lst)div-ds,br,((input-lsb)span-lsbb)span-ds,((input-lsb)span-lsbb)span-ds)td,(a,a)td-fl sblc)tr)table,input-gbv)form,div-gac_scont,(br,((a,a,a,a,a,a,a,a,a)font-addlang,br,br)div-als)div,(((a,a,a,a,a-fehl)div-fll)div,(a)p)span-footer)center,div-xjsd,(script)div-xjsi,script)body)html'

После этого вы можете использовать ETE, как показано в примерах.

Надеюсь, это поможет.

person vivek    schedule 06.01.2013
comment
Можно ли использовать этот python для создания графического представления такого кода html? - person Arup Rakshit; 06.01.2013
comment
@AlexL нет версии для Windows, я использую Windows-7 - person Arup Rakshit; 06.01.2013
comment
Вам понадобится numpy и т. д. — проще всего загрузить их с помощью pip install numpy - person Alex L; 06.01.2013
comment
@AlexL Да, я только что сделал. Пожалуйста, смотрите мое обновленное описание! Некоторые файлы он просил установить. Но у меня не те установлены. Будут ли проблемы? - person Arup Rakshit; 06.01.2013
comment
@PythonLikeYOU Вашей главной задачей будет проанализировать html в формате Newick. - person vivek; 06.01.2013
comment
@vivek будет ли это создавать дерево из html-документа? - person Arup Rakshit; 06.01.2013
comment
Вы используете beautiful soup? - person Alex L; 06.01.2013
comment
@AlexL да я!! Можете ли вы написать @ mynaame при обмене сообщениями, иначе я не получу ваше обновление быстро и ответ тоже! - person Arup Rakshit; 06.01.2013
comment
@PythonLikeYOU, может быть, это было бы полезно? philipbjorge.com/archived_wp_blog/www.philipbjorge.com/2011/12/ - person Alex L; 06.01.2013
comment
@AlexL да, я искал это. пожалуйста, поместите свои предложения в качестве ответа. - person Arup Rakshit; 06.01.2013
comment
@PythonLikeYOU Обновлен ответ с кодом для преобразования htm в формат newick. - person vivek; 06.01.2013
comment
@vivek, но я установил и получил указанную выше ошибку. так это должно работать правильно! Numpy ,PyQt4 не установлены. Они необходимы для запуска вашего кода? - person Arup Rakshit; 06.01.2013
comment
Мой код только конвертирует html в формат newick. Затем вам придется использовать его с ETE; а для ETE вы должны установить pyqt, который используется для рендеринга конечного изображения. - person vivek; 06.01.2013