Как разобрать большую искаженную HTML-страницу в Python?

Я пытаюсь проанализировать большую HTML-страницу с неправильной разметкой таблицы. В таблице около 7000-10000 строк. Проблема в том, что ни один из tr, th, td не закрыт. Итак, разметка такая:

<HTML>
<HEAD>
</HEAD>
<BODY>

<center>

    <table border = 1>
        <tr height=40><th colspan = 16><font size=4>Dummy content
        <tr><th>A
            <th>B
            <th>C
            <th>D
            <th>E
            <th>F
            <th>G


        <tr><td>A
            <td>B
            <td>C
            <td>D
            <td>E
        <tr><td>A
            <td>B
            <td>C
            <td>D
            <td>E
    .........
    .........

    </table>
    </center>
    </BODY>
    </HTML>

Я пытался BeautifulSoup.prettify() исправить это, но BeautifulSoup столкнулся с ошибкой максимальной глубины рекурсии. Также пробовал с lxml следующим образом:

from lxml import html
root = html.fromstring(htmltext)
print len(root.find('.//tr'))

Но он возвращает длину около 50, где на самом деле более 7000 tr.

Есть ли хороший способ проанализировать HTML и извлечь содержимое для каждой строки?


person rahules    schedule 17.07.2015    source источник
comment
могу ли я предложить регулярное выражение?   -  person omri_saadon    schedule 17.07.2015
comment
Ввод действительно выглядит так или вы его переформатировали? Вы можете попробовать что-то вроде замены всех <tr> на </tr><tr>, всех <th> на <\th><th> и т. д., что, безусловно, уменьшит количество ошибок.   -  person 3-14159265358979323846264    schedule 17.07.2015
comment
@omri_saadon, можете ли вы предложить простой пример кода.   -  person rahules    schedule 17.07.2015
comment
@ 3-14159265358979323846264 Я изменил только содержимое внутри тегов, таких как A, B, C и т. д. Структура ввода точно такая же.   -  person rahules    schedule 17.07.2015
comment
@rahules, какие данные вам нужно извлечь? покажите конкретный пример пожалуйста   -  person omri_saadon    schedule 17.07.2015


Ответы (2)


Я надеюсь, что вы ищете что-то вроде этого.

import re
trs = re.findall(r'(?<=<tr>).*?(?=<tr>)', your_string, re.DOTALL)
print trs

это регулярное выражение вернет все между двумя метками tr. если вы хотите искать между двумя другими ярлыками, просто измените первый tr и второй tr на то, что вам нужно.

я провел небольшой тест, и это сработало для меня, дайте мне знать, если это помогло вам.

person omri_saadon    schedule 17.07.2015
comment
Результат поиска возвращает None. pastebin.com/24MjA3af Это pastebin для примера разметки. И да, я ищу извлечение вещей между двумя тр - person rahules; 17.07.2015
comment
@rahules Я отредактировал код, попробуйте и дайте мне знать, пожалуйста - person omri_saadon; 17.07.2015

Я бы предложил попробовать модуль HTMLParser. Я только что написал некоторый код, который его использует, и я не смог протестировать свой блок «кроме HTMLParser.HTMLParseError», потому что я не мог придумать входные данные, которые привели бы к сбою синтаксического анализатора!

person Jonathan Sachs    schedule 17.07.2015