Найти - Пользователи
Полная версия: Как сделать первую букву заглавной
Начало » Python для новичков » Как сделать первую букву заглавной
1 2 3
PSAS
Здравствуйте!
Основная задача программы состоит в том, чтобы сэкономить время на вытягивание данных из pdf документа, особенно если pdf файлов очень много (штук 50 например) либо в нем много обременений/ограничений прописано. Поэтому если бы программа уже могла формирование описание объектов из пдф файлов в таком формате:

“Нежилое здание - склад горюче-смазочных материалов. Назначение: нежилое здание.Площадь: 16.4 кв.м. Количество этажей, в том числе подземных этажей: 1, в том числе подземных 0. Адрес: Российская федерация, Краснодарский край, Усть-лабинский район, ст-ца ладожская, ул.Коншиных, д.100. Кадастровый номер: 23:35:1006004:277.”
http://prntscr.com/1ztcwk1
- сначала идет наименование объекта - берем данные из следующего столбца напротив,
далее назначение, площадь, количество этажей, Адрес, Кадастровый номер (сами слова и их значения).

Если это Земельный участок, то данные берутся в такой последовательности с 1 и 2 страницы ЕГРН:
"Земельный участок, площадью 36240 +/-66.63кв. м, категория земель - Земли населённых пунктов, Виды разрешенного использования:для размещения производственной базы, расположенного по адресу установлено относительно ориентира, расположенного в границах участка. Почтовый адрес ориентира: край Краснодарский, р-н Усть-Лабинский, ст-ца Ладожская, ул.
Коншиных, 111. Кадастровый номер: 23:35:1006004:18"

и второе соответственно каждому объекту указывались его все обременения из раздела 2 пункты 3.
в таком виде

“вид: Ипотека
дата государственной регистрации: 17.01.2018
номер государственной регистрации: 23:35:1006004:277-23/033/2018-3
срок, на который установлено ограничение прав и обременение объекта недвижимости: с 17.01.2018 по 10.10.2020
лицо, в пользу которого установлено ограничение прав и обременение
объекта недвижимости: Акционерное общество Банк ”Северный морской путь“, ИНН: 7750005482
основание государственной регистрации: ‘Договор ипотеки (залога недвижимости) №0800100420.102017КЛ/ДИ-02’ от 12.01.2018”
и т.д.

Достаточно на данном этапе, чтобы данные просто выгружались таким образом для возможности их ручного копирования в вордовский документ, например. Это бы сэкономило бы много времени.
PSAS
ЕГРН ЗУ
xam1816
PSAS
Нежилое здание - склад горюче-смазочных материалов. Назначение: нежилое здание.Площадь: 16.4 кв.м. Количество этажей, в том числе подземных этажей: 1, в том числе подземных 0. Адрес: Российская федерация, Краснодарский край, Усть-лабинский район, ст-ца ладожская, ул.Коншиных, д.100. Кадастровый номер: 23:35:1006004:277.

Прогнал для двух файлов пока только по первым страницам
 import camelot
def get_df_from_pdf(file, pages='1') -> list:
	out = []
	tables = camelot.read_pdf(file, pages=pages)
	for t in tables:
		out.append(t.df)
	return out
def get_info_for_building(dfs:list):
	t0 = dfs[0]
	t1 = dfs[1]
	up = lambda s: s[0].upper() + s[1:]
	low = lambda s: s[0].lower() + s[1:]
	edit_address = lambda s: s.replace('
','')
	name = up(t1[1][6])
	purpose = low(t1[1][5])
	square = t1[1][4]
	num_floors = t1[1][7]
	address = edit_address(t1[1][3])
	cadastral_num = t0[0][4].replace('\n', ' ')
	text = '{name}. Назначение: {purpose}.Площадь: {square} кв.м. ' \
		   'Количество этажей, в том числе подземных этажей: {num_floors}. Адрес: {address}.' \
		   '{cadastral_num}'.format(name=name,
									purpose=purpose,
									square=square,
									num_floors=num_floors,
									address=address,
									cadastral_num=cadastral_num)
	return text
def get_text_from_pdf(file):
	dfs = get_df_from_pdf(file)
	if dfs[0][0][0] == 'Здание':
		return get_info_for_building(dfs)
for f in ['16.4.pdf','496.2.pdf']:
	print(get_text_from_pdf(f))
	print('==============================')

на выходе
 Нежилое здание - склад горюче-смазочных материалов. Назначение: нежилое здание.Площадь: 16.4 кв.м. Количество этажей, в том числе подземных этажей: 1, в том числе подземных 0. Адрес: Российская Федерация, Краснодарский кр., Усть-Лабинский район, ст-ца Ладожская, ул.
Коншиных, 111.Кадастровый номер: 23:35:1006004:277
==============================
Ангар. Назначение: нежилое здание.Площадь: 496.2 кв.м. Количество этажей, в том числе подземных этажей: 1, в том числе подземных 0. Адрес: Краснодарский край, р-н. Усть-Лабинский, ст-ца. Ладожская, ул. Коншиных, д. 111.Кадастровый номер: 23:35:1011002:271
==============================
Process finished with exit code 0
camelot конечно получает текст хорошо,но долго
PSAS
Здравствуйте!
1) Код работает хорошо, но почему-то только на этих ЕГРН, если беру другие (во вложении), то возвращает None.
 import camelot
import glob
pdf_files=glob.glob('*.pdf')
def get_df_from_pdf(file, pages='1-end') -> list:
	out = []
	tables = camelot.read_pdf(file, pages=pages)
	for t in tables:
		out.append(t.df)
	return out
def get_info_for_building(dfs:list):
	t0 = dfs[0]
	t1 = dfs[1]
	up = lambda s: s[0].upper() + s[1:]
	low = lambda s: s[0].lower() + s[1:]
	edit_address = lambda s: s.replace('
','')
	name = up(t1[1][6])
	purpose = low(t1[1][5])
	square = t1[1][4]
	num_floors = t1[1][7]
	address = edit_address(t1[1][3].replace('\n', ' '))
	cadastral_num = t0[0][4].replace('\n', ' ')
	
	text = '{name}. Назначение: {purpose}.Площадь: {square} кв.м. ' \
		   'Количество этажей, в том числе подземных этажей: {num_floors}. Адрес: {address}.' \
		   '{cadastral_num}'.format(name=name,
									purpose=purpose,
									square=square,
									num_floors=num_floors,
									address=address,
									cadastral_num=cadastral_num)
	return text
def get_info_for_landplot(dfs:list):
	t0 = dfs[0]
	t1 = dfs[1]
	t2 = dfs[3]
	up = lambda s: s[0].upper() + s[1:]
	low = lambda s: s[0].lower() + s[1:]
	category = low(t2[1][0])
	purpose = low(t2[1][1])
	square = t1[1][4]
	address = t1[1][3].replace('\n', ' ')
	cadastral_num = t0[0][4].replace('\n', ' ')
	text = 'Земельный участок площадью {square}, расположенный по адресу {address}, '\
		   'категория земель - {category}, разрешенное использование - {purpose}. {cadastral_num}.'.format(category=category,
									purpose=purpose,
									square=square,
									address=address,
									cadastral_num=cadastral_num)
	return text
def get_text_from_pdf(file):
	dfs = get_df_from_pdf(file)
	if dfs[0][0][0] == "Здание":
		return get_info_for_building(dfs)
	if dfs[0][0][0] == "Земельный участок":
		return get_info_for_landplot(dfs)
for f in pdf_files:
	print(get_text_from_pdf(f))
	print('==============================')
2) Думаю как лучше использовать camelot для получения данных об обременениях, если мы точно не знаем в каком файле сколько их - может быть задать цикл который бы их считал по параметру “вид” и далее создать значение, которое бы аккумулировало все эти значения по выписке и код получился бы меньшим. либо использовать лучше pyparsing
xam1816
PSAS
Прикреплённый файлы:
Посмотрю позже
xam1816
Вот как вариант ооочень сырой версии кода,где нет еще поиска обременений и редактирования текста.
Задача не проста тем,что в каждом файле могут быть всякие пробелы,переходы в словах по разному
и постоянно нужно как-то допиливать поиск совпадений.Библиотеки camelot и tabula долго обрабатываю файл,да и таблицы из файлах по разному достаются,т.е универсальный поиск в них та еще задача

на ваших нескольких файлах прогнал, из них вытащились данные,пробуйте на других
 import fitz # pip install PyMuPDF
import re
def get_text(pdf_file):# получает текст из pdf
    print(pdf_file)
    doc = fitz.open(pdf_file)
    text = ''
    for page in doc:
        text += page.get_text()
    doc.close()
    # print(text.encode('1251', 'ignore').decode('1251'))
    return text # возвращает str
print('==========>')
class Building: # класс для здания
    def __init__(self):
        self.name = '???'
        self.purpose = '???'
        self.square = '???'
        self.num_floors = '???'
        self.address = '???'
        self.cadastral_num = '???'
        self.encumbrances = []
    def set_attr(self, text):
        self.name = re.search(r'(?<=Наименование:)(.|\n)+(?=Количество этажей)', text)[0]
            #
        self.purpose = re.search(r'(?<=Назначение:)(.|\n)+(?=Наименование)', text)[0]
            #
        self.square = re.search(r'(?<=Площадь, м²:)(.|\n)+?(?=Назначение:)', text)[0]
            #
        self.num_floors = re.search(
            r'(?<=Количество этажей, в том числе подземных этажей:)(.|\n)+(?=Материал наружных стен)', text)[0]
            #
        self.address = re.search(r'(?<=Адрес:)(.|\n)+(?=Площадь)', text)[0]
            #
        self.cadastral_num = re.search(r'(?<=Кадастровый номер:)(.|\n)+(?=Номер кадастрового квартала:)', text)[0]
    def get_info(self):
        enc_info = ''
        if self.encumbrances:
            enc_info = ''.join(list(map(lambda t:t.get_info(),self.encumbrances)))
        text = '{name}. Назначение: {purpose}.' \
               'Площадь: {square} кв.м. ' \
               'Количество этажей, в том числе подземных этажей: {num_floors}.' \
               ' Адрес: {address}.' \
               'Кадастровый номер: {cadastral_num}\n\n' \
               '{enc_info}'.format(name=self.name,
                                        purpose=self.purpose,
                                        square=self.square,
                                        num_floors=self.num_floors,
                                        address=self.address,
                                        cadastral_num=self.cadastral_num,
                                      enc_info = enc_info)
        return text
class Land: # класс для земельного участка
    def __init__(self):
        self.square = '???'
        self.category = '???'
        self.type_use = '???'
        self.address = '???'
        self.cadastral_num = '???'
        self.encumbrances = []
    def set_attr(self, text):
        self.square = re.search(r'(?<=Площадь:)(.|\n)+?(?=Кадастровая стоимость)', text)[0]
            #
        self.category = re.search(r'(?<=Категория земель:)(.|\n)+?(?=Виды разрешенного использования)', text)[0]
            #
        self.type_use = re.search(r'(?<=Виды разрешенного использования:)(.|\n)+?(?=Сведения о кадастровом инженере:)',
                                  text)[0]
            #
        self.address = re.search(r'(?<=Адрес:)(.|\n)+?(?=Площадь:)', text)[0]
            #
        self.cadastral_num = re.search(r'(?<=Кадастровый номер:)(.|\n)+(?=Номер кадастрового квартала:)', text)[0]
    def get_info(self):
        enc_info = ''
        if self.encumbrances:
            enc_info = ''.join(list(map(lambda t: t.get_info(), self.encumbrances)))
#
        text = 'Земельный участок, площадью {square}, категория земель - {category}, ' \
               'Виды разрешенного использования:{type_use}. ' \
               'Почтовый адрес ориентира: {address}. ' \
               'Кадастровый номер: {cadastral_num}\n\n' \
               '{enc_info}'.format(square=self.square,
                                    category=self.category,
                                    type_use=self.type_use,
                                    address=self.address,
                                    cadastral_num=self.cadastral_num,
                                   enc_info=enc_info)
        return text
#
def get_data(text):# получает данные из текста
    estate = None
    target = re.search(r'((?<=недвижимости:\n)|(?<=недвижимости:)).+(?=\n)',text)
    if target is not None:
        if target[0] == 'Земельный участок':
            estate = Land()
        elif target[0] == 'Здание':
            estate = Building()
        if estate is not None:
            estate.set_attr(text)
            return estate.get_info()
#
def get_directory(): # окно с выбором папки
    print('выбор дирректории')
    import tkinter as tk
    from tkinter import filedialog
    root = tk.Tk()
    root.withdraw()
    dirname = filedialog.askdirectory(parent=root,initialdir="/",title='Please select a directory')
    return dirname # возвращает путь
#
def get_all_pdf_file(dir): # выбирает файлы pdf
    out = []
    import os
    for file in os.listdir(dir):
        if file.endswith('.pdf'):
            out.append(f'{dir}/{file}')
    return out # возвращает список с pdf
#
dir = get_directory()
pdf_file_list = get_all_pdf_file(dir)
#
for f in pdf_file_list:
    text = get_text(f)
    print(get_data(text))
PSAS
Здравствуйте!
Спасибо, не могу запустить код, установил обе библиотеки fitz и PyMuPDF
ModuleNotFoundError: No module named ‘fitz’ Всвязи с чем это может быть?
xam1816
PSAS
No module named ‘fitz’ Всвязи с чем это может быть?
нет надо было только PyMuPDF,
сейчас напишите
 pip uninstall fitz

просто есть две библиотеки fitz, актуальная PyMuPDF
PSAS
Здравствуйте!
по данным егрн не формируются данные
http://prntscr.com/20x0mic
https://disk.yandex.ru/d/EV1kgSo3Wds4KA
xam1816
Вышла новая версия!
.
обновления:
-добавлены другие виды недвижимости
-добавлен вывод обременения
/
не сделано:
- у новых видов недвижимости, нет некоторых параметров(какие именно нужны непонятно,просто скопировал с других)
-нет форматирования данных(в каком виде достались,в том и выводятся)
- и еще,еще,еще,еще,чего нибудь…

для скачивания нажать ctrl-c ctrl-v

 import fitz # pip install PyMuPDF
import re
def get_text(pdf_file):# получает текст из pdf
    print(pdf_file)
    doc = fitz.open(pdf_file)
    text = ''
    for page in doc:
        text += page.get_text()
    doc.close()
    # print(text.encode('1251', 'ignore').decode('1251'))
    return text # возвращает str
print('==========>')
class Room:
    def __init__(self):
        self.name = '???'
        self.purpose = '???'
        self.square = '???'
        self.num_floors = '???'
        self.address = '???'
        self.cadastral_num = '???'
        self.encumbrances = []
    def set_attr(self, text):
        self.name = re.search(r'(?<=Наименование:)(.|\n)+(?=Номер, тип этажа, на котором расположено помещение)', text)[0]
        #
        self.purpose = re.search(r'(?<=Назначение:)(.|\n)+(?=Наименование)', text)[0]
            #
        self.square = re.search(r'(?<=Площадь:)(.|\n)+?(?=Назначение:)', text)[0]
            #
        self.address = re.search(r'(?<=Адрес:)(.|\n)+(?=Площадь)', text)[0]
            #
        self.cadastral_num = re.search(r'(?<=Кадастровый номер:)(.|\n)+(?=Номер кадастрового квартала:)', text)[0]
        #
        iter = re.finditer(r'(?<=3\.1\.\d\.\n)(.|\n)+?((?=3\.1\.\d+\.)|(?=Государственный регистратор))',
                           text)
        self.encumbrances = [i[0] for i in iter]
    def get_info(self):
        enc_info = ''
        if self.encumbrances:
            enc_info = '\n'.join(self.encumbrances)
        text = '{name}. Назначение: {purpose}.' \
               'Площадь: {square} кв.м. ' \
               'Количество этажей, в том числе подземных этажей: {num_floors}.' \
               ' Адрес: {address}.' \
               'Кадастровый номер: {cadastral_num}\n\n' \
               '{enc_info}'.format(name=self.name,
                                        purpose=self.purpose,
                                        square=self.square,
                                        num_floors=self.num_floors,
                                        address=self.address,
                                        cadastral_num=self.cadastral_num,
                                      enc_info = enc_info)
        return text
class Construction:
    def __init__(self):
        self.name = '???'
        self.purpose = '???'
        self.square = '???'
        self.num_floors = '???'
        self.address = '???'
        self.cadastral_num = '???'
        self.encumbrances = []
    def set_attr(self, text):
        self.name = re.search(r'(?<=Наименование:)(.|\n)+(?=Количество этажей)', text)[0]
            #
        self.purpose = re.search(r'(?<=Назначение:)(.|\n)+(?=Наименование)', text)[0]
            #
        self.address = re.search(r'(?<=Адрес:)(.|\n)+(?=Основная характеристика \(для сооружения\):)', text)[0]
            #
        self.cadastral_num = re.search(r'(?<=Кадастровый номер:)(.|\n)+(?=Номер кадастрового квартала:)', text)[0]
        #
        iter = re.finditer(r'(?<=3\.1\.\d\.\n)(.|\n)+?((?=3\.1\.\d+\.)|(?=Государственный регистратор))',
                           text)
        self.encumbrances = [i[0] for i in iter]
    def get_info(self):
        enc_info = ''
        if self.encumbrances:
            enc_info = '\n'.join(self.encumbrances)
        text = '{name}. Назначение: {purpose}.' \
               'Площадь: {square} кв.м. ' \
               'Количество этажей, в том числе подземных этажей: {num_floors}.' \
               ' Адрес: {address}.' \
               'Кадастровый номер: {cadastral_num}\n\n' \
               '{enc_info}'.format(name=self.name,
                                        purpose=self.purpose,
                                        square=self.square,
                                        num_floors=self.num_floors,
                                        address=self.address,
                                        cadastral_num=self.cadastral_num,
                                      enc_info = enc_info)
        return text
class Building: # класс для здания
    def __init__(self):
        self.name = '???'
        self.purpose = '???'
        self.square = '???'
        self.num_floors = '???'
        self.address = '???'
        self.cadastral_num = '???'
        self.encumbrances = []
    def set_attr(self, text):
        self.name = re.search(r'(?<=Наименование:)(.|\n)+(?=Количество этажей)', text)[0]
            #
        self.purpose = re.search(r'(?<=Назначение:)(.|\n)+(?=Наименование)', text)[0]
            #
        self.square = re.search(r'(?<=Площадь, м²:)(.|\n)+?(?=Назначение:)', text)[0]
            #
        self.num_floors = re.search(
            r'(?<=Количество этажей, в том числе подземных этажей:)(.|\n)+(?=Материал наружных стен)', text)[0]
            #
        self.address = re.search(r'(?<=Адрес:)(.|\n)+(?=Площадь)', text)[0]
            #
        self.cadastral_num = re.search(r'(?<=Кадастровый номер:)(.|\n)+(?=Номер кадастрового квартала:)', text)[0]
        #
        iter = re.finditer(r'(?<=3\.1\.\d\.\n)(.|\n)+?((?=3\.1\.\d+\.)|(?=Государственный регистратор))',
                           text)
        self.encumbrances = [i[0] for i in iter]
    def get_info(self):
        enc_info = ''
        if self.encumbrances:
            enc_info = '\n'.join(self.encumbrances)
        text = '{name}. Назначение: {purpose}.' \
               'Площадь: {square} кв.м. ' \
               'Количество этажей, в том числе подземных этажей: {num_floors}.' \
               ' Адрес: {address}.' \
               'Кадастровый номер: {cadastral_num}\n\n' \
               '{enc_info}'.format(name=self.name,
                                        purpose=self.purpose,
                                        square=self.square,
                                        num_floors=self.num_floors,
                                        address=self.address,
                                        cadastral_num=self.cadastral_num,
                                      enc_info = enc_info)
        return text
class Land: # класс для земельного участка
    def __init__(self):
        self.square = '???'
        self.category = '???'
        self.type_use = '???'
        self.address = '???'
        self.cadastral_num = '???'
        self.encumbrances = []
    def set_attr(self, text):
        self.square = re.search(r'(?<=Площадь:)(.|\n)+?(?=Кадастровая стоимость)', text)[0]
            #
        self.category = re.search(r'(?<=Категория земель:)(.|\n)+?(?=Виды разрешенного использования)', text)[0]
            #
        self.type_use = re.search(r'(?<=Виды разрешенного использования:)(.|\n)+?(?=Сведения о кадастровом инженере:)',
                                  text)[0]
            #
        self.address = re.search(r'(?<=Адрес:)(.|\n)+?(?=Площадь:)', text)[0]
            #
        self.cadastral_num = re.search(r'(?<=Кадастровый номер:)(.|\n)+(?=Номер кадастрового квартала:)', text)[0]
        #
        iter = re.finditer(r'(?<=3\.1\.\d\.\n)(.|\n)+?((?=3\.1\.\d+\.)|(?=Государственный регистратор))',
                                       text)
        self.encumbrances = [i[0] for i in iter]
    def get_info(self):
        enc_info = ''
        if self.encumbrances:
            enc_info = '\n'.join(self.encumbrances)
#
        text = 'Земельный участок, площадью {square}, категория земель - {category}, ' \
               'Виды разрешенного использования:{type_use}. ' \
               'Почтовый адрес ориентира: {address}. ' \
               'Кадастровый номер: {cadastral_num}\n' \
               '{enc_info}'.format(square=self.square,
                                    category=self.category,
                                    type_use=self.type_use,
                                    address=self.address,
                                    cadastral_num=self.cadastral_num,
                                   enc_info=enc_info)
        return text
#
def get_data(text):# получает данные из текста
    estate = None
    target = re.search(r'((?<=недвижимости:\n)|(?<=недвижимости:)).+(?=\n)',text)
    if target is not None:
        if target[0] == 'Земельный участок':
            estate = Land()
        elif target[0] == 'Здание':
            estate = Building()
        elif target[0] == 'Сооружение':
            estate = Construction()
        elif target[0] == 'Помещение':
            estate = Room()
        if estate is not None:
            estate.set_attr(text)
            return estate.get_info()
#
def get_directory(): # окно с выбором папки
    print('выбор дирректории')
    import tkinter as tk
    from tkinter import filedialog
    root = tk.Tk()
    root.withdraw()
    dirname = filedialog.askdirectory(parent=root,initialdir="/",title='Please select a directory')
    return dirname # возвращает путь
#
def get_all_pdf_file(dir): # выбирает файлы pdf
    out = []
    import os
    for file in os.listdir(dir):
        if file.endswith('.pdf'):
            out.append(f'{dir}/{file}')
    return out # возвращает список с pdf
#
dir = get_directory()
pdf_file_list = get_all_pdf_file(dir)
for f in pdf_file_list:
    text = get_text(f)
    res = get_data(text)
    print(res)
    print('=====')
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB