diff --git a/Emendas_Parlamentares_202212/Emendas.csv b/Emenda_Parlamentar_20231103/Emendas.csv similarity index 100% rename from Emendas_Parlamentares_202212/Emendas.csv rename to Emenda_Parlamentar_20231103/Emendas.csv diff --git a/execucao.py b/execucao.py deleted file mode 100644 index fabf443..0000000 --- a/execucao.py +++ /dev/null @@ -1,90 +0,0 @@ -import os -import pandas as pd -import requests as rq -from methods.loaders.filesSave import FileSavers -from methods.transformers.transformData import TransformData -from methods.extractors.webPageDataScrapers import WebPageDataScrapers -from utils.tools import GeneralTools -import utils.logger_config as logger_config -from utils.charts import GeneralCharts -from utils.aws import AboutAWS -import logging -import seaborn as sns - -def main(): - try: - fileSavers = FileSavers() - transformData = TransformData() - webPageDataScrapers = WebPageDataScrapers() - generalTools = GeneralTools() - generalCharts = GeneralCharts() - df = pd.DataFrame() - client = AboutAWS() - # Variável contendo informações das moedas a serem coletadas, aws e banco de dados - jsonData = generalTools.openJson() - logger_config.setup_logger(generalTools.getDate()) - - # Configurando para 4 casas decimais a formatação e exibição dos n°s com ponto flutuante - pd.options.display.float_format = '{:.4f}'.format - logging.info("CONFIGURAÇÃO PARA 4 CASAS DECIMAIS NOS N°S COM PONTO FLUTUANTE REALIZADA COM SUCESSO.") - - file_name = transformData.getFileName(jsonData) - directory_name = f"{jsonData['source']['generalLink']['params']['directory']}{file_name.split('_')[-1].split('.')[0]}" - logging.info("NOME DO DIRETÓRIO COLETADO COM SUCESSO.") - reference_date = file_name.split("_")[-1].split(".")[0] if isinstance(file_name, str) else 'HISTÓRICA' - logging.info("DATA REFERÊNCIA COLETADA COM SUCESSO.") - file_name = iter([file_name]) if isinstance(file_name, str) else iter(file_name) - generalTools.makeDirectory(directory_name) - logging.info("NOME DO ARQUIVO COLETADO COM SUCESSO.") - fund_data = [] - - html, soup = webPageDataScrapers.requestGetDefault(jsonData['source']['generalLink']['url']) - webPageDataScrapers.extractZip(html, "EmendasParlamentares.zip", directory_name) - logging.info("INFORMAÇÕES DO ARQUIVO BAIXADA COM SUCESSO.") - #zip_file = webPageDataScrapers.readZipFile(jsonData['source']['generalLink']['url'], directory_name) - #fund_data.append(fileSavers.readDeepData(zip_file)) - #logging.info("LEITURA E ARMAZENAMENTO DO CONTEÚDO DO ZIP REALIZADO COM SUCESSO.") - - registration_data = fileSavers.readRegistrationData() - logging.info("ARMAZENANDO DADOS DE REGISTRO SOBRE OS CNPJS.") - filtered_fund_data = transformData.gettingMonthlyReturn(fund_data) - final_base = fileSavers.mergeDataFrames(filtered_fund_data, registration_data) - logging.info("MESCLANDO OS DADOS ATRAVÉS DA COLUNA CNPJ E ESCOLHE AS COLUNAS DESEJADAS.") - largest_values, fund_names, quota_values, fund_cnpjs, index, historical_data = fileSavers.gettingTheBestInvestmentFunds(final_base, jsonData['source']['generalLink']['params']['toprange']) - logging.info(f"ORGANIZANDO DADOS E FILTRANDO OS {jsonData['source']['generalLink']['params']['toprange']} MELHORES FUNDOS.") - final_base = transformData.ajustingColumns(final_base) - - # Análise dos 'toprange' (inserido no data.json) fundos com maiores Patrimônios Líquidos - generalCharts.createBarhChart([10, 6], fund_names, fund_cnpjs, largest_values, reference_date, directory_name, jsonData['source']['generalLink']['params']['toprange']) - logging.info("GRÁFICO DE ANÁLISE DOS 'TOPRANGE' FUNDOS COM MAIORES PATRIMÔNIOS LÍQUIDOS.") - - # Análise da Evolução do Valor Patrimonial Líquido dos 'toprange' ao Longo do Tempo - generalCharts.netAssetValueEvolution([10, 8], final_base, 'Evolução do Valor Patrimonial Líquido', 'Datas', 'Valores Patrimoniais Líquidos (R$)', 90, reference_date, directory_name, fund_names, fund_cnpjs, largest_values) - logging.info("GRÁFICO DE ANÁLISE DA EVOLUÇÃO DO VALOR PATRIMONIAL LÍQUIDO DOS 'TOPRANGE' AO LONGO DO TEMPO.") - - # Análise da Distribuição dos Tipos de Fundos ocupados no 'toprange' (TP_FUNDO) - generalCharts.barChart([10, 8], final_base[final_base['DENOM_SOCIAL'].isin(fund_names)], 'DENOM_SOCIAL', 'TP_FUNDO', 'Distribuição dos Tipos de Fundos do TopRange', 'Tipo de Fundo', 'Quantidade por Tipo Fundos (Int)', 45, reference_date, directory_name, 'DistribuicaoTiposMelhoresFundos') - logging.info("GRÁFICO DE ANÁLISE DA DISTRIBUIÇÃO DOS TIPOS DE FUNDOS OCUPADOS NO 'TOPRANGE'.") - - # Análise da Distribuição Geral dos Tipos de Fundos (TP_FUNDO) - generalCharts.barChart([10, 8], final_base, 'DENOM_SOCIAL', 'TP_FUNDO', 'Distribuição Geral dos Tipos de Fundos', 'Tipo de Fundo', 'Quantidade por Tipo Fundos (Int)', 45, reference_date, directory_name, 'DistribuicaoTiposFundos') - logging.info("GRÁFICO DE ANÁLISE DA DISTRIBUIÇÃO GERAL DOS TIPOS DE FUNDOS OCUPADOS NO 'TOPRANGE'.") - - fileSavers.dfToCsv(final_base, f'{directory_name}/FundosInvestimentoGeral_{directory_name.split("_")[-1]}.csv', "\t") - fileSavers.dfToCsv(final_base[final_base['CNPJ_FUNDO'].isin(fund_cnpjs)], f'{directory_name}/FundosInvestimentoTopRange_{directory_name.split("_")[-1]}.csv', "\t") - - s3 = client.createClient('s3') - for arquivos in os.listdir(directory_name): - localfile = f"{directory_name}/{arquivos}" - client.uploadFile(s3, localfile, 'engdadostest', localfile) - logging.info(f"TODOS OS ARQUIVOS (ZIP, CSV E GRÁFICOS) INSERIDOS NA PASTA {directory_name} FORAM INSERIDOS NO BUCKET RESPECTIVO'.") - - except FileNotFoundError as err: - logging.error(f"ERRO: {generalTools.upperCase(err)}, O ARQUIVO JSON (data.json) NÃO FOI ENCONTRADO.") - except (rq.exceptions.HTTPError, rq.exceptions.RequestException) as err: - logging.error(f"ERRO DURANTE A REQUISIÇÃO: {generalTools.upperCase(err)}") - except Exception as err: - logging.error(f"ERRO DESCONHECIDO: {generalTools.upperCase(err)}") - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/methods/__pycache__/__init__.cpython-311.pyc b/methods/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 0758e0d..0000000 Binary files a/methods/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/methods/extractors/__pycache__/webPageDataScrapers.cpython-311.pyc b/methods/extractors/__pycache__/webPageDataScrapers.cpython-311.pyc deleted file mode 100644 index 3ee9082..0000000 Binary files a/methods/extractors/__pycache__/webPageDataScrapers.cpython-311.pyc and /dev/null differ diff --git a/methods/extractors/webPageDataScrapers.py b/methods/extractors/webPageDataScrapers.py deleted file mode 100644 index d05a1c1..0000000 --- a/methods/extractors/webPageDataScrapers.py +++ /dev/null @@ -1,58 +0,0 @@ -#import boto3 -import zipfile -import os -import io -import requests as rq -from bs4 import BeautifulSoup as bs4 -import utils.logger_config as logger_config -import logging -import locale -from utils.tools import GeneralTools -from utils.aws import AboutAWS - -generalTools = GeneralTools() -jsonData = generalTools.openJson() -locale.setlocale(locale.LC_ALL, 'pt_BR.utf8') -logger_config.setup_logger(generalTools.getDate()) - -class WebPageDataScrapers: - def __init__(self): - self.client = AboutAWS() - - def readZipFile(self, nome_zip: str, namedirectory: str): - return zipfile.ZipFile(f"{namedirectory}/{nome_zip}") - - def extractZip(self, response, nome_zip: str, namedirectory: str): - generalTools.makeDirectory(namedirectory) - with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref: - # Extrai o conteúdo do arquivo zip para o diretório atual - zip_ref.extractall(path=namedirectory) - - # Remova o arquivo ZIP depois de extraído - #os.remove(nome_zip) - - def downloadUrl(self, response, nome_arquivo, namedirectory): - with open(f"{namedirectory}/{nome_arquivo}", 'wb') as file: - file.write(response.content) - #client = self.client.createClient('s3') - #self.client.uploadFile(client, nome_arquivo, 'engdadostest', nome_arquivo) - - def requestGetDefault(self, link: str): - try: - headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', - 'Referer': f"{link}" - } - html = rq.get(link, headers=headers) - html.raise_for_status() - soup = bs4(html.text, 'html.parser') - - except rq.exceptions.HTTPError as http_err: - logging.error(f"Erro HTTP: {http_err}") - logging.error("Recurso não encontrado - Erro 404.") if html.status_code == 404 else logging.error("Outro erro HTTP ocorreu.") - except rq.exceptions.RequestException as req_err: - logging.error(f"Erro de Requisição: {req_err}") - except Exception as err: - logging.error(f"Erro Desconhecido: {err}") - - return html, soup \ No newline at end of file diff --git a/methods/loaders/__pycache__/filesSave.cpython-311.pyc b/methods/loaders/__pycache__/filesSave.cpython-311.pyc deleted file mode 100644 index bbc7986..0000000 Binary files a/methods/loaders/__pycache__/filesSave.cpython-311.pyc and /dev/null differ diff --git a/methods/loaders/filesSave.py b/methods/loaders/filesSave.py deleted file mode 100644 index 347edcc..0000000 --- a/methods/loaders/filesSave.py +++ /dev/null @@ -1,94 +0,0 @@ -import fastavro -import pandas as pd -import utils.logger_config as logger_config -from utils.tools import GeneralTools -from methods.transformers.transformData import TransformData -import logging -from utils.charts import GeneralCharts -generalCharts = GeneralCharts() -generalTools = GeneralTools() -transformData = TransformData() -logger_config.setup_logger(generalTools.getDate()) - -class FileSavers: - def __init__(self): - pass - - def openingSheets(self, directory: str, sheet: str, rows: int, footer: int): - return pd.read_excel(f"{directory}", sheet_name=f"{sheet}", skiprows=rows, skipfooter=footer) - - def dfToCsv(self, df: pd.DataFrame, file_name: str, separator: str): - df.to_csv(file_name, sep=separator, index=False) - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO EXCEL REALIZADA COM SUCESSO.") - return df.to_csv() - - def dfToExcel(self, df: pd.DataFrame, file_name: str, sheet_name='Sheet1'): - df.to_excel(file_name, sheet_name=sheet_name, index=False) - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO EXCEL REALIZADA COM SUCESSO.") - return df.to_excel() - - def dfToJson(self, df: pd.DataFrame, file_name: str): - df.to_json(file_name, orient='records') - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO JSON REALIZADA COM SUCESSO.") - return df.to_json() - - def dfToParquet(self, df: pd.DataFrame, file_name: str): - df.to_parquet(file_name, index=False) - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO PARQUET REALIZADA COM SUCESSO.") - return df.to_parquet() - - def df_to_pickle(self, df: pd.DataFrame, file_name: str): - df.to_pickle(file_name) - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO PICKLE REALIZADA COM SUCESSO.") - return df.to_pickle() - - def df_to_avro(self, df: pd.DataFrame, file_name: str): - with open(file_name, 'wb') as out_avro: - fastavro.writer(out_avro, df.to_dict(orient='records')) - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO AVRO REALIZADA COM SUCESSO.") - return df - - def df_to_html(self, df: pd.DataFrame, file_name: str): - df.to_html(file_name, index=False) - logging.info("CONVERSÃO DO DATAFRAME PARA TIPO HTML REALIZADA COM SUCESSO.") - return df.to_html() - - def concatDataFrame(self, df: pd.DataFrame, dictionary: dict, index: int): - try: - return pd.concat([df, pd.DataFrame(dictionary, index=[index])]) - except KeyError as e: - logging.error(f"ERRO: {e}, A CHAVE {e} NÃO FOI ENCONTRADA NO DICIONÁRIO.") - except Exception as e: - logging.error(f"ERRO: {e}, NÃO FOI POSSÍVEL CONCATENAR OS DATAFRAMES.") - - def readDeepData(self, zip_file): - return pd.read_csv(zip_file.open(zip_file.namelist()[0]), sep=";", encoding="ISO-8859-1") - - #def readRegistrationData(self): - # dados_cadastro = pd.read_csv('https://dados.cvm.gov.br/dados/FI/CAD/DADOS/cad_fi.csv', #sep=";", encoding="ISO-8859-1") - # - # dados_cadastro = dados_cadastro[['CNPJ_FUNDO', 'DENOM_SOCIAL']] - # - # dados_cadastro = dados_cadastro.drop_duplicates() - # return dados_cadastro - - def mergeDataFrames(self, dados_fundos_filtrado, dados_cadastro): - base_final = pd.DataFrame() - for fundos_filtrados in dados_fundos_filtrado: - merged_df = pd.merge(fundos_filtrados, dados_cadastro, how="left", left_on =["CNPJ_FUNDO"], right_on = ["CNPJ_FUNDO"]) - base_final = pd.concat([base_final, merged_df], ignore_index=True) - - return base_final[['CNPJ_FUNDO', 'DENOM_SOCIAL', 'TP_FUNDO', 'DT_COMPTC', 'VL_TOTAL', 'VL_QUOTA', 'VL_PATRIM_LIQ', 'NR_COTST']] - - def gettingTheBestInvestmentFunds(self, base_final: pd.DataFrame, range: int): - aux_base = base_final - # Usando, como referência e parâmetro, o último dia como dia 30, e removendo duplicados - base_final = base_final[pd.to_datetime(base_final['DT_COMPTC']).dt.day == 30] - - # Coletando os 'range' maiores valores, usando como referência o Patrimônio Líquido - maiores_valores = base_final['VL_PATRIM_LIQ'].nlargest(range) - nomes_fundos = base_final.loc[maiores_valores.index, 'DENOM_SOCIAL'] - valores_cota = base_final.loc[maiores_valores.index, 'VL_QUOTA'] - cnpjs_fundos = base_final.loc[maiores_valores.index, 'CNPJ_FUNDO'] - - return maiores_valores, nomes_fundos, valores_cota, cnpjs_fundos, maiores_valores.index, aux_base[aux_base['DENOM_SOCIAL'].isin(nomes_fundos)].index \ No newline at end of file diff --git a/methods/transformers/__pycache__/__init__.cpython-311.pyc b/methods/transformers/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 6ddcd42..0000000 Binary files a/methods/transformers/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/methods/transformers/__pycache__/transformData.cpython-311.pyc b/methods/transformers/__pycache__/transformData.cpython-311.pyc deleted file mode 100644 index 7437edd..0000000 Binary files a/methods/transformers/__pycache__/transformData.cpython-311.pyc and /dev/null differ diff --git a/methods/transformers/transformData.py b/methods/transformers/transformData.py deleted file mode 100644 index f3f293e..0000000 --- a/methods/transformers/transformData.py +++ /dev/null @@ -1,64 +0,0 @@ -import datetime -import time -import pandas as pd -import utils.logger_config as logger_config -import logging -import fastavro -from utils.tools import GeneralTools -from methods.extractors.webPageDataScrapers import WebPageDataScrapers - -generalTools = GeneralTools() -webPageDataScrapers = WebPageDataScrapers() - -logger_config.setup_logger(time.strftime("%Y-%m-%d %H:%M:%S")) - -class TransformData: - def __init__(self): - self.data = generalTools.splitByEmptySpace(generalTools.getDate())[0] - - def selectingData(self, df: pd.DataFrame, title: str, data: list): - return df[df[title].isin(data)] - - def format_Date(self, date: str): - try: - return datetime.datetime.strptime(str(date), "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d") - except: - return "" - - def cleaningDataRepeated(self, data: list): - if data[-1] == data[-2]: - data.pop() - return data - - def cleaningEmptySpace(self, data: list, product): - return list(filter(lambda item: item != '', data)) + [product] - - def deletingColumns(self, df: pd.DataFrame, diames: str): - arg = str(datetime.datetime.strptime(diames, "%Y-%m-%d").strftime("%b/%y")).title() - count = 2 - for f in range(0, len(df.columns)): - if arg != df.iloc[0][-2]: - df = df.drop(columns=df.columns[len(df.columns)-count:]) - elif arg == df.iloc[0][-2]: - return df - - def getFileName(self, jsonData: dict): - return f"{jsonData['source']['generalLink']['params']['namefile']}{jsonData['source']['generalLink']['params']['year']}{jsonData['source']['generalLink']['params']['month']}" if jsonData['source']['generalLink']['params']['year'] != '' else f"{jsonData['source']['generalLink']['params']['namefile']}Historico" - - def gettingMonthlyReturn(self, dados_fundos: pd.DataFrame): - generalData = [] - for dados in dados_fundos: - #data_inicio_mes = (dados['DT_COMPTC'].sort_values(ascending = True).unique())[0] - #data_fim_mes = (dados['DT_COMPTC'].sort_values(ascending = True).unique())[-1] - #generalData.append(dados[(dados['DT_COMPTC'].isin([data_inicio_mes, data_fim_mes]))]) - generalData.append(dados) - return generalData - - def ajustingColumns(self, base_final: pd.DataFrame): - base_final['DENOM_SOCIAL'] = base_final['DENOM_SOCIAL'].map(lambda x: generalTools.barToNull(generalTools.cleaningDataStr(x)), na_action='ignore') - base_final['DT_COMPTC'] = pd.to_datetime(base_final['DT_COMPTC']) - base_final = base_final.query('VL_TOTAL > 0 and VL_PATRIM_LIQ > 0 and VL_QUOTA > 0') - - base_final.reset_index(inplace=True) - base_final = base_final.drop('index', axis=1) - return base_final \ No newline at end of file diff --git a/teste.ipynb b/teste.ipynb new file mode 100644 index 0000000..4abe2bc --- /dev/null +++ b/teste.ipynb @@ -0,0 +1,88 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Importações\n", + "import pandas as pd\n", + "import requests as rq\n", + "import zipfile\n", + "import datetime\n", + "import io\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# Atribuições\n", + "# URL do arquivo zip que você deseja baixar\n", + "\n", + "url = 'https://portaldatransparencia.gov.br/download-de-dados/emendas-parlamentares/UNICO'\n", + "\n", + "headers = {\n", + " 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',\n", + " 'Referer': f\"{url}\"\n", + "}\n", + "\n", + "data = datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n", + "\n", + "name_directory = f\"Emenda_Parlamentar_{data.split(' ')[0].replace('-','')}\"\n", + "\n", + "if not os.path.exists(name_directory):\n", + " os.makedirs(name_directory)\n", + "\n", + "response = rq.get(url, headers=headers)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Extraindo arquivos do zip e inserindo no diretório desejado\n", + "with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:\n", + " #zip_ref.extractall(path=namedirectory)\n", + " zip_ref.extractall(path=name_directory)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# Lendo arquivo CSV usando pd.read_csv\n", + "df_csv = pd.read_csv(f'{name_directory}/Emendas.csv', sep=';', encoding='ISO-8859-1')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}