LINUX.ORG.RU

при сравнении строк, что-то пошло не так

 ,


0

1

downloaded_file.html

<table>
    <tr>
        <td>Nu1</td>
        <td>546</td>
    </tr>
    <tr>
        <td>Number one</td>
        <td>342</td>
    </tr>
    <tr>
        <td>Nu3</td>
        <td>456</td>
    </tr>
</table>

file_template.html

<table>
    <tr>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
    </tr>
</table>

Пишем, пишем код.

with open("file_template.html") as file_template:
    template_list = file_template.readlines()

with open("file_downloaded.html") as file_downloaded:
    downloaded_list = file_downloaded.readlines()


list_counter = 0
result_string=''
counter_i=0
while list_counter != len(downloaded_list):
    if downloaded_list[list_counter] != template_list[list_counter]:
        for i in range(len(template_list[list_counter])):
            if downloaded_list[list_counter][i] != template_list[list_counter][i]:
                counter_i = i
                #while  # пока символ с позиции template_list не сравняется с символом из downloaded_list
                result_string += downloaded_list[list_counter][counter_i]
        result_string += ","
    else:
        pass
    list_counter += 1
print(result_string)


И тут, как водится, что-то пошло не так:

Nu1</t,546</t,Number,342</t,Nu3</t,456</t,
А ожидалось так:
Nu1,546,Number one,342,Nu3,456

★★★★★

Последнее исправление: sniper21 (всего исправлений: 4)

res = map(lambda x: x[0].replace('<td>', '').replace('</td>', '').strip(),
          filter(lambda x: x[0] != x[1],
                 zip(downloaded_list, template_list)))
print(map(lambda x: '%s, %s' % x, zip(res[::2], res[1::2])))
['Nu1, 546', 'Number one, 342', 'Nu3, 456']
vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)
Ответ на: комментарий от vvn_black
<td>

хардкодить нельзя, да ничего хардкодить нельзя, к сожалению, так как могут быть другие символы

sniper21 ★★★★★
() автор топика
Последнее исправление: sniper21 (всего исправлений: 2)

Когда ты начинаешь читать значение из таблицы в первом файле тебе нужно переставать двигаться по второму.

zip тут, похоже, не очень подходит. Реши задачу «в лоб»: циклом while и счетчиками, значения которых сам менять будешь.

Dmit3Y
()
Ответ на: комментарий от sniper21

Я не знаю, какие у тебя ещё ограничения, но если там только один закрытый тэг, то:

res = list(map(lambda x: x[0][x[0].find('>') + 1: x[0].rfind('<')],
               filter(lambda x: x[0] != x[1],
                      zip(downloaded_list, template_list))))
print(list(map(lambda x: '%s, %s' % x, zip(res[::2], res[1::2]))))

А если, нужна универсальность, то как здраво подсказал анон, надо парсить html специально обученой либой.

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 2)
Ответ на: комментарий от vvn_black

Я сейчас парсю html специально обученной libxml2 на C++, проблема в том что есть много разных страничек которые надо парсить. Пытаюсь сделать универсальный вариант на шаблонах:

  • сделал шаблон (удалив интересующие значения)
  • скачал страничку
  • прогнал по шаблону
  • записал в xml
sniper21 ★★★★★
() автор топика

Ты хотел посимвольное сравнение строк, ты его получил. Работает как написал.

frob ★★★★★
()

Ты хотел посимвольное сравнение строк, ты его получил. Работает как написал.

Virtuos86 ★★★★★
()

А везде пишут, что надо складывать кусочки строк в массив и на выходе делать join

makoven ★★★★★
()
Ответ на: комментарий от sniper21

Счетчики для шаблона и загруженного текста должны быть разные.

result_strings = []
for downloaded_line, template_line in zip(downloaded_list, template_list):
    template_counter, downloaded_counter, diff_symbols = 0, 0, []
    while downloaded_counter < len(downloaded_line):
        if downloaded_line[downloaded_counter] == template_line[template_counter]:
            downloaded_counter += 1
            template_counter += 1
            continue
        diff_symbols.append(downloaded_line[downloaded_counter])
        downloaded_counter += 1
    if diff_symbols:
        result_strings.append(''.join(diff_symbols))
result_string = ','.join(result_strings)

print(result_string)

Вот. Выглядит правда жутко, но работает как ты хочешь.

Dmit3Y
()
Ответ на: комментарий от Dmit3Y

Даже на таких данных? ) Я не думаю, что html-ки и шаблоны будут такими красивыми - каждый элемент на отдельной строке.

downloaded_list = """
<table>
    <tr><td>Nu1</td><td>546</td></tr>
    <tr>
        <td>Number one</td><td>342</td>
    </tr>
    <tr>
        <td>Nu3</td>
        <td>456</td>
    </tr>
</table>
"""

template_list = """
<table>
    <tr><td></td><td></td></tr>
    <tr>
        <td></td><td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
    </tr>
</table>
"""
vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

Не, на таких не будет. Мой вариант запятые добавляет после каждой обработанной строки.

Да и в принципе такой подход не очень рабочий, но ТСу хочется)

Dmit3Y
()
Ответ на: комментарий от Dmit3Y

А ещё простая вёрстка - это фантастика, всё больше такое:

<tr><td>Значение: <pre><code class="lang-html"><td>42</td></code></pre></td><td>546</td></tr>

а в итоге надо получить Значение: 42, и каким шаблоном разрулить?

vvn_black ★★★★★
()
Ответ на: комментарий от Dmit3Y

Примерно такое же я написал сам, только циклов у меня три :-)

sniper21 ★★★★★
() автор топика
Ответ на: комментарий от Dmit3Y

Спасибо за труды, может кому тоже потребуется :)

sniper21 ★★★★★
() автор топика
Ответ на: комментарий от sniper21

Если ты таки уперся в эту фигню (а в этом тут никто не сомневался)), то уж лучше взять, как советовали выше, полноценный парсер, который сможет разобрать весь код и достать то, что нужно.

Если все же хочешь продолжать мучатся с тем что есть, попробуй удалить переносы строк. Но это путь в никуда, упрешься во что-то другое.

Dmit3Y
()
Ответ на: комментарий от Dmit3Y

Ещё раз: я взял нормальный парсер libxml2, парсю всё по циклу, но страничек пара сотен. Мне получится надо писать парсер для каждой отдельно, с сотней if типа встретилась табличка, тоггда одно, если вместо таблички div то другое или я чего-то не понимаю?

т.е. распарсить не проблема - проблема вытащить то, что нужно, и кроме как использовать условия я не знаю как.

sniper21 ★★★★★
() автор топика
Последнее исправление: sniper21 (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.