Форум сайта python.su
Генератор отчётов FastReport выгружает таблички в html, в которых ячейки представлены тегами <div>
Это выглядит так:
<div class="s8" style="left:946.39px;top:61.83px;width:61.37px;height:42.89px;"><div class="s7">Стоимость, руб.</div></div> <div class="s10" style="left:88.33px;top:61.83px;width:53.81px;height:42.89px;"><div class="s9">Дата</div></div> <div class="s12" style="left:143.14px;top:61.83px;width:46.25px;height:42.89px;"><div class="s11">Время</div></div> <div class="s14" style="left:190.39px;top:61.83px;width:492.29px;height:42.89px;"><div class="s13">Вид услуги</div></div> <div class="s16" style="left:683.68px;top:61.83px;width:63.26px;height:42.89px;"><div class="s15">Набранный номер, точка доступа</div></div> <div class="s18" style="left:747.94px;top:61.83px;width:93.5px;height:42.89px;"><div class="s17">Местонахождение при использовании услуги</div></div> <div class="s20" style="left:842.44px;top:61.83px;width:102.95px;height:42.89px;"><div class="s19">Объём</div></div> <div class="s22" style="left:-0.5px;top:61.83px;width:87.83px;height:42.89px;"><div class="s21">Номер устройства (IMEI)</div></div> <div class="s23" style="left:0px;top:106.22px;width:1009.26px;height:24.45px;"> </div> <div class="s25" style="left:88.33px;top:105.72px;width:53.81px;height:23.45px;"><div class="s24">04.10.2021</div></div> <div class="s27" style="left:143.14px;top:105.72px;width:46.25px;height:23.45px;"><div class="s26">06:54:47</div></div> <div class="s29" style="left:190.39px;top:105.72px;width:492.29px;height:23.45px;"><div class="s28">Исх. на мобильные дом. региона, Билайн; Пензенская Область, моб. связь, Билайн</div></div> <div class="s31" style="left:683.68px;top:105.72px;width:63.26px;height:23.45px;"><div class="s30">89699900000</div></div> <div class="s33" style="left:747.94px;top:105.72px;width:93.5px;height:23.45px;"><div class="s32">Пензенская обл.</div></div> <div class="s35" style="left:842.44px;top:105.72px;width:48.14px;height:23.45px;"><div class="s34">9,00</div></div> <div class="s37" style="left:-0.5px;top:105.72px;width:87.83px;height:23.45px;"><div class="s36"></div></div> <div class="s38" style="left:891.58px;top:105.72px;width:53.81px;height:23.45px;"><div class="s24">Секунда</div></div> <div class="s40" style="left:946.39px;top:105.72px;width:61.37px;height:23.45px;"><div class="s39">0,00</div></div> <div class="s23" style="left:0px;top:130.67px;width:1009.26px;height:24.45px;"> </div>
kol4 = tree.xpath('//div[contains(@style, "left:190.39px;")]/div/text()') #Вид услуги
print (kol4, len(kol4))
kol7 = tree.xpath('//div[contains(@style, "left:842.44px;")]/div/text()') #Объём
print (kol7, len(kol7))
kol8 = tree.xpath('//div[contains(@style, "left:891.58px")]/div/text()') #Ед.изм.
print (kol8, len(kol8))
kol4 = tree.xpath('//div[(@class="s29" or @class="s47")]/div/node()') #Вид услуги
kol7 = tree.xpath('//div[(@class="s35" or @class="s53")]/div/node()') #Объём
kol8 = tree.xpath('//div[(@class="s38" or @class="s56")]/div/node()') #Ед.изм.
Отредактировано Cyr (Окт. 13, 2021 15:53:49)
Офлайн
Решил тупо в лоб эту задачу
def spliting(line):
start=line.rfind('">')+2
end=line.rfind('</div></div>')
mes='"'+line[start:end]+'"'
return mes
f = open('c:/Downloads/Детализация.html', encoding="utf-8")
for line in f:
if line.rfind('left:190.39px;')>0:
print (spliting(line), end=';')
elif line.rfind('left:842.44px;')>0:
print (spliting(line), end=';')
elif line.rfind('left:891.58px;')>0:
print (spliting(line))
Отредактировано Cyr (Окт. 13, 2021 14:17:55)
Офлайн
CyrПроблема в том, что ты ищешь по атрибуту style. Это самое глупое, что можно было сделать.
С учётом того что некоторые ячейки могут быть пустые.
CyrГде здесь отчёт? Это лишь маленький кусочек чего-то целого. И что значит “некоторые ячейки могут быть пустые”? Это отсутствие тегов для них или просто наличие тегов, но отсутствие текста в них?
Как получить данные из этого отчёта?
Отредактировано py.user.next (Окт. 13, 2021 14:48:29)
Офлайн
py.user.nextОтступы слева в стиле определяют положение колонок таблицы. По ним определяем что это за колонка. По class тоже можно искать. Но в одной колонке они бывают с несколькими именами.
Проблема в том, что ты ищешь по атрибуту style. Это самое глупое, что можно было сделать.
py.user.nextЭто заголовок и первая строка из таблицы. Дальше там строки повторяются.
Где здесь отчёт? Это лишь маленький кусочек чего-то целого.
py.user.nextОтсутствие текста в последних тегах div.
И что значит “некоторые ячейки могут быть пустые”? Это отсутствие тегов для них или просто наличие тегов, но отсутствие текста в них?
Отредактировано Cyr (Окт. 13, 2021 15:49:32)
Офлайн
CyrНе, это понятно. Просто стили меняются каждые три секунды. По ним нельзя ориентироваться, потому что через неделю их сделают другими и вся твоя программа сломается из-за этого. И так будет повторяться каждый раз. Надо более стабильные признаки выбирать (один признак или устойчивую группу признаков).
Отступы слева в стиле определяют положение колонок таблицы.
CyrПриведи полный пример. Приведи таблицу на три записи хотя бы. На ней и можно поискать стабильные признаки для определения строк и для определения полей в строках. Не говорю колонки, так как колонки не всегда являются минимальными элементами, составляющими строку.
По class тоже можно искать.
CyrОтсутствующий текст видно хорошо. Надо просто по-другому записывать его поиск. То есть не факт, что там именно XPath надо применять.
Отсутствие текста в последних тегах div.
Отредактировано py.user.next (Окт. 13, 2021 22:33:05)
Офлайн
Выложи сюда вот этот файл
c:/Downloads/Детализация.html
Офлайн
xam1816Во вложении реальный файл с нереальными номерами.
Выложи сюда вот этот файл
py.user.nextНу вот корректно работающий скрипт:
Отсутствующий текст видно хорошо. Надо просто по-другому записывать его поиск. То есть не факт, что там именно XPath надо применять.
# -*- coding: utf-8 -*- # Скрипт импорта детализации html в csv def spliting(line): start=line.rfind('">')+2 end=line.rfind('</div></div>') mes=line[start:end] return mes.replace(' ', ' ') f = open('c:/Downloads/Детализация.html', encoding="utf-8") out = open('c:/Downloads/Детализация.csv', 'w') for line in f: if line.rfind('class="s29"')>0: # Вид услуги исх. out.write ('"'+spliting(line)+'";') elif line.rfind('class="s47"')>0: # Вид услуги вх. out.write ('"'+spliting(line)+'";') elif line.rfind('class="s35"')>0: # Объём исх. out.write (spliting(line)+';') elif line.rfind('class="s53"')>0: # Объём вх. out.write (spliting(line)+';') elif line.rfind('class="s38"')>0: # Ед.изм. исх out.write ('"'+spliting(line)+'"\n') elif line.rfind('class="s56"')>0: # Ед.изм. вх. out.write ('"'+spliting(line)+'"\n') out.close
Отредактировано Cyr (Окт. 14, 2021 09:32:36)
Прикреплённый файлы:
Детализация.html (220,2 KБ)
Офлайн
CyrТам несколько страниц. Их надо соединить в одну? Соединить несколько страниц в одну и потом каждый блок из девяти полей превратить в одну строку в CSV-файле?
Прикреплённый файлы:
attachment Детализация.html (220,2 KБ)
Офлайн
py.user.nextМой скрипт корректно выбирает нужные поля (всего 3) по class, соединяет их в строку. И проходит он по всем страницам. div, в которых колонтитулы и остальные поля он игнорирует же.
Соединить несколько страниц в одну и потом каждый блок из девяти полей превратить в одну строку в CSV-файле?
Отредактировано Cyr (Окт. 14, 2021 10:43:23)
Офлайн
CyrОпиши, что нужно сделать, без своего скрипта. Словами опиши. Вот файл детализации, из него надо выбрать поля с тем-то и тем-то и сохранить их так-то и так-то.
Мой скрипт корректно выбирает нужные поля (всего 3) по class из всех страниц.
CyrТы не думал, что close - это функция такая и её надо вызвать с помощью круглых скобочек?out.close
Отредактировано py.user.next (Окт. 14, 2021 10:46:40)
Офлайн