Доброго времени суток!
Возникла необходимость получить данные из отчета рабочей программы, отчет в HTML.
Собственно HTML документ(Выкладываю только блок где находятся необходимые данные, если нужно дополнительно залью весь файл):
Установил модуль Beautiful Soup, немного почитал документацию и написал следующий скрипт:
#!/usr/bin/env python # -*- coding: utf-8 -*- from bs4 import BeautifulSoup f = open('File1.HTML', 'rb') doc = f.read() soup = BeautifulSoup(doc) rez = [] for x in soup.find_all('font', size="2"): rez.append(x.contents[0]) if x.contents[0] == 'ВЕС: ': #Велосипед для ограничения выхода из диапазона break inp = [] for y in range(1000): if str(rez[y]) == 'НОМЕР ЧЕРТЕЖА: ': inp.append([rez[y], rez[y+1]]) print(inp)
Очень всё шатко, и ограничение по циклу, будет работать если у меня отчет на одно изделие. Идея в том, что получить данные из всех font, затем прогнать результат в цикле и найти с помощью If-ов необходимые данные, для примера допустим нужно извлечь поле "РАЗМЕРЫ: " и соответственно значение этого поля "377.000 x 77.000 mm ".
Сомнительный результат, поэтому не могли бы вы подсказать как это лучше реализовать?
Полный HTML файл(оформлен ужасно):
ПЛАН НАЛАДКИ ОБЩИЕ ПАРАМЕТРЫ |
Antonov
25.08.2015 TruTops Laser V10.00.00 |
ИНФОРМАЦИЯ ОБ ОТД. ДЕТАЛИ | |
НОМЕР ДЕТАЛИ: | 1 |
НОМЕР ЧЕРТЕЖА: | 425900-92.08.101 |
ИМЯ ЧЕРТЕЖА: | |
ЗАКАЗЧИКА: | |
КОЛИЧЕСТВО: | 4 |
РАЗМЕРЫ: | 377.000 x 77.000 mm |
ПОВЕРХНОСТЬ: | 29029.00 mm2 |
ИМЯ СВОДА ПРАВИЛ: | 5P |
НОМЕР ПОДПРОГРАММЫ: | SP1DOR_SHEST_BR6 / SP3DOR_SHEST_BR6 |
ВРЕМЯ ОБРАБОТКИ: | 0.47 min (PierceLine: 0.47 min) |
ДЛИНА РЕЗКИ: | 1241.13 mm |
ВЕС: | 1.823 kg |
КОЛ-ВО ТОЧЕК ВРЕЗАНИЯ: | 1 |
ВРЕМЯ ВРЕЗАНИЯ | 0.17 (PierceLine: 0.06) s |
ИМЯ ГЕОМ. ФАЙЛА: | D:\Programs TRUMPF\2015\№101 Крой изделия 425901-92.00.010-10 (доп.1)\Крой ч10\425900-92.08.101.GEO |
ПРЕДВ. НАЧЕРЧ. РАЗМЕТКА: | SP1DOR_SHEST_BR6 - 0.13 min |
НОМЕР ДЕТАЛИ: | 2 |
НОМЕР ЧЕРТЕЖА: | 425900-92.08.102 |
ИМЯ ЧЕРТЕЖА: | |
ЗАКАЗЧИКА: | |
КОЛИЧЕСТВО: | 4 |
РАЗМЕРЫ: | 264.000 x 77.000 mm |
ПОВЕРХНОСТЬ: | 20328.00 mm2 |
ИМЯ СВОДА ПРАВИЛ: | 5P |
НОМЕР ПОДПРОГРАММЫ: | SP2DOR_SHEST_BR6 / SP4DOR_SHEST_BR6 |
ВРЕМЯ ОБРАБОТКИ: | 0.42 min (PierceLine: 0.42 min) |
ДЛИНА РЕЗКИ: | 1023.53 mm |
ВЕС: | 1.277 kg |
КОЛ-ВО ТОЧЕК ВРЕЗАНИЯ: | 1 |
ВРЕМЯ ВРЕЗАНИЯ | 0.17 (PierceLine: 0.06) s |
ИМЯ ГЕОМ. ФАЙЛА: | D:\Programs TRUMPF\2015\№101 Крой изделия 425901-92.00.010-10 (доп.1)\Крой ч10\425900-92.08.102.GEO |
ПРЕДВ. НАЧЕРЧ. РАЗМЕТКА: | SP2DOR_SHEST_BR6 - 0.15 min |
Ответ
Можно воспользоваться тем, что все детали определены в одной таблице. В этом файле такая таблица находится однозначно с помощью поиска:
table = soup.find('table', width="600", border="1",
cellspacing="1", cellpadding="0")
Далее можно выбрать все строки таблицы с помощью поиска
trs = list(table.find_all('tr'))
Для удобства итерации я преобразовал результат поиска в список. Использовал то, что поля в таблице идут в одном и том же порядке и в последовательных строках. Всего таких строк 15.
Осталась задача найти начало записи, после чего её уже разобрать. Начало записи обозначается строкой таблицы, содержащей строку 'НОМЕР ДЕТАЛИ:'. Для простоты кода я использовал цикл for, но при желании можно использовать ручную итерацию. Возможно, она будет работать немного быстрее.
Также заметил, что на странице используются неразрывные пробелы. Они имеют код \xa0. Я их преобразовываю в обычные, при желании можно их убрать, на исполнение скрипта это не влияет.
Далее разбор строк. Каждая интересующая нас строка состоит из двух элементов. Первый отвечает за имя, второй -- за значение. Пробегаюсь по всем этим строкам и сохраняю почищенные значения в кортеж.
Вот полный код скрипта:
from bs4 import BeautifulSoup
def clear_string(s):
return s.replace('\xa0', ' ').strip()
def parse_detail(detail_rows):
return tuple(tuple(clear_string(text) for text in row.strings)
for row in detail_rows)
start_row_name = 'НОМЕР ДЕТАЛИ:'
rows_count = 15
with open('File1.HTML') as in_file:
soup = BeautifulSoup(in_file.read())
table = soup.find('table', width="600", border="1",
cellspacing="1", cellpadding="0")
trs = list(table.find_all('tr'))
details = []
for i, tr in enumerate(trs):
strings = tuple(clear_string(text) for text in tr.strings)
if len(strings) == 2 and strings[0] == start_row_name:
details.append(parse_detail(trs[i : i + rows_count]))
print(details)
Результат работы скрипта на представленной странице:
# [(('НОМЕР ДЕТАЛИ:', '1'),
# ('НОМЕР ЧЕРТЕЖА:', '425900-92.08.101'),
# ('ИМЯ ЧЕРТЕЖА:', ''),
# ('ЗАКАЗЧИКА:', ''),
# ('КОЛИЧЕСТВО:', '4'),
# ('РАЗМЕРЫ:', '377.000 x 77.000 mm'),
# ('ПОВЕРХНОСТЬ:', '29029.00 mm2'),
# ('ИМЯ СВОДА ПРАВИЛ:', '5P'),
# ('НОМЕР ПОДПРОГРАММЫ:', 'SP1DOR_SHEST_BR6 / SP3DOR_SHEST_BR6'),
# ('ВРЕМЯ ОБРАБОТКИ:', '0.47 min (PierceLine: 0.47 min)'),
# ('ДЛИНА РЕЗКИ:', '1241.13 mm'),
# ('ВЕС:', '1.823 kg'),
# ('КОЛ-ВО ТОЧЕК ВРЕЗАНИЯ:', '1'),
# ('ВРЕМЯ ВРЕЗАНИЯ', '0.17 (PierceLine: 0.06) s'),
# ('ИМЯ ГЕОМ. ФАЙЛА:',
# 'D:\\Programs TRUMPF\\2015\\№101 Крой изделия 425901-92.00.010-10 '
# '(доп.1)\\Крой ч10\\425900-92.08.101.GEO')),
# (('НОМЕР ДЕТАЛИ:', '2'),
# ('НОМЕР ЧЕРТЕЖА:', '425900-92.08.102'),
# ('ИМЯ ЧЕРТЕЖА:', ''),
# ('ЗАКАЗЧИКА:', ''),
# ('КОЛИЧЕСТВО:', '4'),
# ('РАЗМЕРЫ:', '264.000 x 77.000 mm'),
# ('ПОВЕРХНОСТЬ:', '20328.00 mm2'),
# ('ИМЯ СВОДА ПРАВИЛ:', '5P'),
# ('НОМЕР ПОДПРОГРАММЫ:', 'SP2DOR_SHEST_BR6 / SP4DOR_SHEST_BR6'),
# ('ВРЕМЯ ОБРАБОТКИ:', '0.42 min (PierceLine: 0.42 min)'),
# ('ДЛИНА РЕЗКИ:', '1023.53 mm'),
# ('ВЕС:', '1.277 kg'),
# ('КОЛ-ВО ТОЧЕК ВРЕЗАНИЯ:', '1'),
# ('ВРЕМЯ ВРЕЗАНИЯ', '0.17 (PierceLine: 0.06) s'),
# ('ИМЯ ГЕОМ. ФАЙЛА:',
# 'D:\\Programs TRUMPF\\2015\\№101 Крой изделия 425901-92.00.010-10 '
# '(доп.1)\\Крой ч10\\425900-92.08.102.GEO'))]
Комментариев нет:
Отправить комментарий