И так, в обычный день был обнаружен человек с простой задачей:
нужно было через каждый "экран текста" в html-файле вставить специальный тег. Задача простая и не особо под автоматизацию, пока не видишь файл примерно на 400к символов (среднестатистическая страница А4 печатного текста ~1800 символов => 200 страниц.
С такими объемами уже руками сражаться сложно. Приступим.
И так, я вооружился python3 и BeautifulSoup (ранее уже писал про него).
Перед тем как работать, стоит обратить внимание на html. В моём случае это оказался текст "Сохраненный как" html из Microsoft Office. Если кто не знает, у офиса это получается весьма своеобразным путём. Так как уже существует готовое решение, я не стал замарачиваться и писать свой велосипед. Очень рекомендую программу Doc2html. Для сравнения: исходный файл полученный мной весил 1,3 МБ - после конвертирования вес составил 698 КБ. Ощутимо.
Так же, обнаружим, что html из офиса в кодировке CP1251, а после конвертера UTF8.
Сам скрипт
Точность не требовалась по ТЗ. Логика скрипта простая:
Делаем итерацию по всем параграфам (<p></p>) и измеряем длину каждого в символах. В том же цикле, мы прочли больше символов, чем заданное Х - вставляем наш тег.
def pagin(htmlin,htmlout,psize,pstart,charset):
from bs4 import BeautifulSoup
itercounter = 0
page = pstart
with open(htmlin, 'r',encoding=charset) as file: #
bs = BeautifulSoup(file.read(), 'html.parser')
pps = bs.findAll('p')
for p in pps: #reversed
itercounter += len(p.text)
sum += len(p.text)
if itercounter >= psize:
sp = str(page)
tag = bs.new_tag('hr', **{'class':'system','title':'Страница %s' % (sp) })
p.insert(0,tag)
itercounter = 0
page +=1
with open(htmlout,'w') as fo:
fo.write(str(bs.html))
Конечно, скрипт получился не идеальным - с не маленькой погрешностью, но нас устраивает.
Вставляемый тег:
<hr class="system" title="страница n" />
Он может быть любой. Из кода вполне понятно, как сделать аналогичный объект.GUI для скрипта
Скрипт изначально рассчитывался на "блондинку". Ранее, в скриптах для себя я использовал модуль argparse и управление скриптом было из командной строки. Но как только я начал описывать параметры - я понял что для "блондинки" и тем более из под Windows будет сложно его использовать. А если автоматизацию сложнее использовать, чем исходный процесс - она не работает.
Я задумался об GUI. В GUI был выбран TK так как он интегрирован в python что бы завести скрипт на другой машине - нужно меньше телодвижений (об этом позже).
Это мой второй интерфейс. Первый я реализовал на PyQT4 и был не доволен количеством телодвижений для простого интерфейса. В этом плане TK оказался легким и простым.
Да, сразу скажу, что я не стал обрабатывать всевозможные исключения и интерфейс не идеален. Но по трудочасам - минимален, что и требовалось.
Для написания интерфейса мне хватило трёх страничек в интернете и времени на него ушло даже меньше, чем на основную функцию.
from tkinter import *
from tkinter.filedialog import *
def pagin(htmlin,htmlout,psize,pstart,charset):
...
def button_clicked():
htmlin = askopenfilename()
htmlout = asksaveasfilename()
if listboxKind.curselection()[0] == 0:
charset = 'utf8'
elif listboxKind.curselection()[0] == 1:
charset = 'cp1251'
psize = SizeEnt.get()
pstart = StartEnt.get()
pagin(htmlin,htmlout,int(psize),int(pstart),charset)
print(htmlin,htmlout,psize,pstart,charset)
root=Tk()
listboxKind=Listbox(root,height=2,width=15,selectmode=SINGLE)
listKind = ['utf8 (doc2html)','cp1251 (MSOffice)']
for i in listKind:
listboxKind.insert(END,i)
Label(root,text="Тип html").pack()
listboxKind.pack()
Label(root,text="Период в символах").pack()
SizeEnt= Entry(root,width=10)
SizeEnt.pack()
Label(root,text="Начало отсчета").pack()
StartEnt = Entry(root,width=10)
StartEnt.pack()
button1 = Button(root,text='Открыть файл',command=button_clicked)
button1.pack()
root.mainloop()
![]() |
Python+TK |
askopenfilename, asksaveasfilename.
Что очень приятно упрощает жизнь.диалоги:
Просто, но работает. Теперь точно не запутаться в параметрах и аргументах командной строки.
Переносимость скрипта
Написал - молодец, но надо ещё отдать этот скрипт "блондинке".
Существует, на мой взгяд, два пути:
- Отдать скрипт (1,8 КБ)
А в месте с ним иструкцию, как установить python3, beautifulSoup научить этим пользоваться. Благо TK идет в комплекте, и не надо дополнительно ничего качать, собственно по этому он и был выбран.
Но, оставим этот вариант на черный день. - Скомпилировать скрипт в полноценный exe (27 МБ)
Тогда есть чётко exe файл который надо запускать, и минимум объяснений, что радует. Что не радует, так это размер. Ну что уж, 21 век, "8мб хватит всем" =)
Данная приблуда, вместе со скриптом кладёт сам интерпретатор Python и все библиотеки, которые используются в скрипте. py2exe достаточно самостоятелен, но иногда требуется указать ему что надо собрать с собой, к примеру дополнительные библиотеки или статические файлы.
Для сборки необходимо положить рядом со скриптом специальный файл setup.py. В моём случае, всё собралось с первого раза:
#!/usr/bin/python3
from distutils.core import setup
import py2exe
setup(
windows=[{"script":"paginator_03.py"}],
options={"py2exe": {"includes":[]}}
)
И выполняем команду уже под windows :python3 setup.py py2exe
Готово. 27 метров скрипта на 2 кб.
Открытые вкладки
- http://ginstrom.com/software/doc2html/ Программа конвертер MS html в нормальный html
- http://wiki.python.su/Документация/BeautifulSoup
- Про GUI на TK
- http://younglinux.info/tkinter.php
- http://www.ibm.com/developerworks/ru/library/l-python_details_09/index.html#N10087
- https://ru.wikiversity.org/wiki/Курс_по_библиотеке_Tkinter_языка_Python
- https://sohabr.net/habr/post/87224/"Немного про py2exe"
Комментариев нет:
Отправить комментарий