2013-05-25 1 views
0

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

I.e. дали вход:

<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 с дополнительными модулями или без них.

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

ответ

3

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

Parse HTML table to Python list?

Но использовать 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 
+0

Благодарим вас за код, но проблема в том, что он обрабатывает только один специальный случай, и мой фактический ввод немного сложнее и содержит много colspans, поэтому он не будет отображать данные так, как я этого хочу. Вот пример фактических данных: http://pastebin.com/yRQvz2Ww На данный момент ни один из параметров, которые я пробовал (elementree, lxml, BeautifulSoup), не приближается к выходу 'w3m -dump' со входом, который я имею , – ccpizza

+0

Это совершенно другой вопрос - я имею в виду * данный ввод * и * ожидаемый результат * не то, что вы просили. Для чего вы сначала спросили, мой ответ работает. –

+0

Мой оригинальный пример - * generic *, и предпочтительный ответ в идеале должен быть * generic *. Решение, которое вы предлагаете, решает простейший случай, но недостаточно * generic *. – ccpizza

1

You может использовать 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.

+0

Спасибо! Потрясающие! Что-то классное, чтобы играть с :) Возможности веб-подкачки библиотеки выглядят привлекательно, и скорость также впечатляет. Через некоторое время я расскажу о своих результатах. – ccpizza