Форма № 16

от автора

Преподаватели, работающие в российских ВУЗах, периодически сталкиваются с необходимостью предоставить администрации список своих научных и учебно-методических работ. Например, для (пере)избрания на должность, присвоения звания и т. д. Формат представления информации, форма № 16, разработан невесть когда и до сих пор используется в бюрократических недрах Министерства Науки и Высшего Образования РФ. Мне стало лень заполнять эту форму вручную и я написал небольшой python сценарий, который генерирует нужную таблицу на основе информации, полученной из научной электронной библиотеки elibrary.ru. Возможно, кому-то это будет интересно, так что ниже приведено описание этой процедуры…

Итак, для начала нужно зайти на сайт elibrary.ru, авторизоваться, перейти в раздел «авторам» и далее в «мои публикации». Справа на экране есть колонка «инструменты», в которой есть кнопка «Вывести на печать список публикаций автора». Нажимаем на нее и в отдельном окне получаем таблицу со списком публикаций, которую сохраняем себе на диск в виде html-файла, который для простоты назовем index.html. Каждая публикация в этом списке выглядит примерно так:

Строка таблицы от elibrary.ru
Строка таблицы от elibrary.ru

Однако согласно приказу №268 Минобрнауки РФ (приложение №3 на с. 52) таблица зачем-то должна выглядеть иначе:

Строка таблицы в соответствии с формой №16
Строка таблицы в соответствии с формой №16

Сценарий для преобразования формата таблицы основан на использовании библиотеки BeautifulSoup, с которой я ознакомился весьма поверхностно и использовал первый раз в жизни. Вот что у меня вышло:

#!/usr/bin/env python3 from bs4 import BeautifulSoup from random import randint from re import findall   YFrom, YTo = 2015, 2020                              # фильтр по годам публикаций  def NP(s): # функция для непредвзятого определения количества страниц в статье   pages = s.split()[-1]   if '-' in pages:     P = pages.split('-')     np =  1 + int(float(P[1])-float(P[0]))   else:     np = randint(5, 10)   return '%d' % np # возвращает строку с числом    def Year(s, FROM, TO): # функция для отбора по году публикации   Ys = findall(r'\s\d{4}\.', content)                 # форма записи года ' 2020.'   if not Ys: Ys = findall(r'\s\d{4}', content)        # форма записи года ' 2020'   if not Ys: return False        # если ничего не нашлось - выбрасываем                                for y in Ys: Y = int(float(y)) # в случае более чем одного совпадения берем последнее   if Y<FROM or Y>TO: return False    else:              return True  with open('index.html', 'r') as fp:    soup = BeautifulSoup(fp, 'html.parser')              # загружаем исходный файл soup.head.style.decompose()                            # убираем заголовок, css и т.д. aname = soup.title.get_text().split('-')[1]            # имя автора aname = f'СПИСОК опубликованных и приравненных к ним научных и учебно-методических работ {aname:s}\n' soup.title.string = aname                              # новый заголовок soup.find('span').string = aname                       # новый заголовок soup.find('i').decompose()                             # убираем что-то лишнее soup.find('table').decompose()                         # находим и удаляем первую таблицу table = soup.find('table')                             # находим вторую таблицу table['border'] = 1                                    # меняем оформление table['width']  = '100%'                               # меняем ширину N = 1                                                  # новый счетчик  rows = table.find_all('tr')                            # ищем все строки в таблице for i in range(len(rows)):                             # цикл для замены содержимого строк   cols = rows[i].find_all('td')                        # ищем все столбцы   if len(cols)==3 and cols[1].find('span'):            # проверка на соответствие стандартному шаблону     content = cols[1].get_text()                       # читаем запись из второго столбца     title   = cols[1].find('span').get_text()          # тут название     authors = cols[1].find('i').get_text()             # тут авторы     cites   = int(cols[2].get_text())                  # количество цитирований статьи     content = content.replace(title, '')               # убираем навзвание, убираем список авторов:     content = content.replace(authors, '')             # в content остаются только выходные данные     thesis  = content.replace('В сборнике: ','')       # далее идет определение типа публикации     abbook  = content.replace('В книге: ','')          #      if   thesis != content:                            #       title += ' (тезисы)';      content = thesis      #     elif abbook != content:                            #       title += ' (тезисы)';      content = abbook      #     else:                                              #       if 'автореф'  in content: title+= ' (монография)'#       elif 'диссер' in content: title+= ' (монография)'#       else: title += ' (статья)'                       #     authors = authors.split(', ')                      # получаем список авторов     if cites<10 or not Year(content, YFrom, YTo):      # некоторые записи можно выбросить       rows[i].decompose()                              #     else:                                              # для других - определить кол-во соавторов        anumber = len(authors)       if anumber<5: PS = ''       else:         PS = f' и др., всего {anumber:d} чел.'       authors = ', '.join(authors[0:5]) + PS        cols[0].string = f'{N:3d}'                        # показания счетчика       cols[1].string = title                            # название       cols[2].string = "печ."                           # тип работы       for info in [content, NP(content), authors]:      # еще три столбца          A = soup.new_tag('td');  A.string = info ; rows[i].append(A)       N+= 1   else:     rows[i].decompose()  tr = soup.new_tag('tr') # вставляем заголовок таблицы names = ['№ п\п', 'Наименование работы, её вид', 'Форма работы', 'Выходные данные', 'Объём в п.л. или с.', 'Соавторы'] for name in names:   th = soup.new_tag('th')    th.string = name   tr.append(th)  table.insert(0, tr)    with open('table.html', 'w', encoding='utf-8') as fp: fp.write(str(soup))    

Для выполнения задачи нужно запустить сценарий в папке, в которой содержится файл index.html, в который мы сохранили таблицу с elibrary.ru. На выходе генерируется файл table.html, который можно легко загрузить в google docs, где и подвергнуть окончательным правкам типа изменения ширин столбцов, выбора шрифтов и т.д.

ссылка на оригинал статьи https://habr.com/ru/post/558190/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *