Решение Python для преобразования таблиц HTML в читаемый обычный текст

Я ищу способ чистого преобразования HTML-таблиц в читаемый обычный текст.

т.е. при вводе:

<table>
    <tr>
        <td>Height:</td>
        <td>200</td>
    </tr>
    <tr>
        <td>Width:</td>
        <td>440</td>
    </tr>
</table>

Я ожидаю вывод:

Height: 200
Width: 440

Я бы предпочел не использовать внешние инструменты, например. w3m -dump file.html, потому что они (1) зависят от платформы, (2) я хочу иметь некоторый контроль над процессом и (3) я предполагаю, что это выполнимо с одним Python с дополнительными модулями или без них.

Мне не нужен перенос слов или регулируемая ширина разделителя ячеек. Наличие табуляции в качестве разделителя ячеек было бы достаточно.

Обновлять

Это был старый вопрос для старого варианта использования. Учитывая, что pandas предоставляет метод read_html, мой текущий ответ будет определенно будет на основе панд.


person ccpizza    schedule 25.05.2013    source источник


Ответы (3)


Как насчет использования этого:

Разбирать таблицу HTML в список Python?

Но используйте collections.OrderedDict() вместо простого словаря, чтобы сохранить порядок. После того, как у вас есть словарь, очень-очень легко получить и отформатировать текст из него:

Используя решение @Colt 45:

import xml.etree.ElementTree
import collections

s = """\
<table>
    <tr>
        <th>Height</th>
        <th>Width</th>
        <th>Depth</th>
    </tr>
    <tr>
        <td>10</td>
        <td>12</td>
        <td>5</td>
    </tr>
    <tr>
        <td>0</td>
        <td>3</td>
        <td>678</td>
    </tr>
    <tr>
        <td>5</td>
        <td>3</td>
        <td>4</td>
    </tr>
</table>
"""

table = xml.etree.ElementTree.XML(s)
rows = iter(table)
headers = [col.text for col in next(rows)]
for row in rows:
    values = [col.text for col in row]
    for key, value in collections.OrderedDict(zip(headers, values)).iteritems():
        print key, value

Вывод:

Height 10
Width 12
Depth 5
Height 0
Width 3
Depth 678
Height 5
Width 3
Depth 4
person Peter Varo    schedule 25.05.2013
comment
Спасибо за пример кода, но проблема в том, что он обрабатывает только один особый случай, а мой фактический ввод немного сложнее и содержит много столбцов, поэтому он не будет отображать данные так, как я этого хочу. Вот пример фактических данных: pastebin.com/yRQvz2Ww На данный момент ни один из вариантов, которые я пробовал ( elementree, lxml, BeautifulSoup) приближаются к выходу w3m -dump с вводом, который у меня есть. - person ccpizza; 25.05.2013
comment
Это совсем другой вопрос — я имею в виду, что данные входные данные и ожидаемые результаты — это не то, что вы просили. Для того, что вы спросили первым, мой ответ работает. - person Peter Varo; 25.05.2013
comment
Мой первоначальный пример — общий, и в идеале предпочтительным ответом также будет общий. Предлагаемое вами решение действительно решает простейший случай, но оно недостаточно общее. - person ccpizza; 25.05.2013

Вам следует взглянуть на стандартные библиотечные модули ElementTree и минидом

person Oin    schedule 25.05.2013

Вы можете использовать модуль HTQL по адресу http://htql.net.

Вот пример кода для вашей страницы:

import urllib2
url='http://pastebin.com/yRQvz2Ww'
page=urllib2.urlopen(url).read();

query="""<div (ID='super_frame')>1.<div (ID='monster_frame')>1.<div (ID='content_frame')>1.<div (ID='content_left')>1.<div (ID='code_frame2')>1.<div (ID='code_frame')>1.<div (ID='selectable')>1.<div (CLASS='html4strict')>1 &tx
<table>.<tr>{
    c1=<td>:colspan;   t1=<td>1 &tx; 
    c2=<td>2:colspan;   t2=<td>2 &tx;
    c3=<td>3:colspan;   t3=<td>3 &tx; 
    c4=<td>4:colspan;   t4=<td>4 &tx;
    c5=<td>5:colspan;   t5=<td>5 &tx;
}
"""

for t in htql.query(page, query): 
    print('\t'.join(t)); 

htql.query() создает 10 столбцов, включая c1, t2, c2, t2, ... c5, t5. Вы можете использовать информацию c1..c5, чтобы узнать, в каких ячейках должны находиться t1..t5.

person seagulf    schedule 27.05.2013