Path: blob/main/Lab11/Scraper_Contraloria.ipynb
2714 views
Kernel: Python 3 (ipykernel)
In [1]:
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.support.ui import Select import pandas as pd from pandas import Series,DataFrame from pandas import ExcelWriter import time from time import sleep import re import os import urllib.request def scraper_contraloria(region,responsabilidad='example,',periodo='example'): try: options = webdriver.ChromeOptions() # driver = webdriver.Chrome(ChromeDriverManager().install(),options=options) driver_path = './chromedriver_win32/chromedriver.exe' driver = webdriver.Chrome(driver_path,options=options) driver.get('https://appbp.contraloria.gob.pe/BuscadorCGR/Informes/Avanzado.html') driver.maximize_window() # Convertimos las alternativas ingresadas en mayusculas(es asi como lo ubicaremos en el Dom): region = region.upper() responsabilidad = responsabilidad.upper() # Damos click en Responsabilidad, segun la alternativa ingresada. try: personas_cpr = driver.find_element_by_xpath('//*[@id="lblResponsabilidad"]//ul') personas_cpr.location_once_scrolled_into_view personas_cp = personas_cpr.find_element_by_partial_link_text(responsabilidad) personas_cp.click() except: print('\nResponsabilidad no especificada.\nSe an procesado todas las responsabilidades.\n') # Tal ves ingresan la opcion 'P. C. DEL CALLAO' sin los puntos, aca los colocamos para ubicarlo en el Dom. if region == 'P C DEL CALLAO': region = 'P. C. DEL CALLAO' else: pass # Damos click en la region ingresada, con 2 intentos: try: # si la opción ingresada(REGION) esta ubicada en la ventana por defecto, con estas 4 lineas bastara. continuo_link = driver.find_element_by_xpath('//*[@id="lblRegion"]/ul') continuo_link.location_once_scrolled_into_view continue_link = continuo_link.find_element_by_partial_link_text(region) continue_link.click() except: # amos click en 'VER MAS' para extender las opciones. element = driver.find_element_by_xpath('//*[@id="lblRegion"]/ul/li[4]/label') element.location_once_scrolled_into_view element.click() # Ahora podremos ubicar nuestra opcion ingresada(REGION) le damos click. continuo_link = driver.find_element_by_xpath('//*[@id="lblRegion"]/ul/li[4]/div/ul') continue_link = continuo_link.find_element_by_partial_link_text(region)#aqui continue_link.location_once_scrolled_into_view continue_link.click() # Escogemos 'MUNICIPALIDADES DISTRITALES' esta opción estara marcada por defecto en nuestro codigo. element = driver.find_element_by_xpath('//*[@id="lblSector"]/ul/li[1]/a/label/p') element.location_once_scrolled_into_view element.click() # Seleccionamos 'Periodo de emisión del informe' solo si se ah ingresado una opción. try: try: # si la opción ingresada(Periodo) esta ubicada en la ventana por defecto, con estas 4 lineas bastara. periods = driver.find_element_by_xpath('//*[@id="lblPeriodo"]/ul') periods.location_once_scrolled_into_view perio = periods.find_element_by_partial_link_text(periodo)#aqui perio.click() except: # Damos click en 'VER MAS' para extender las opciones. element = driver.find_element_by_xpath('//*[@id="lblPeriodo"]/ul/li[4]/label') element.location_once_scrolled_into_view element.click() # Ahora podremos ubicar nuestra opcion ingresada(Periodo) le damos click. periods = driver.find_element_by_xpath('//*[@id="lblPeriodo"]/ul') periods.location_once_scrolled_into_view perio = periods.find_element_by_partial_link_text(periodo)#aqui perio.click() except: print('Periodo sin especificar.\n\nSe an procesado todos los Periodos. ') # Limpiamos las palabras(opciones) ingresadas para poder transcribirlas en las carpetas que se crearan despues. region = region.replace(' ','_') if '.' in region: region = region.replace('.','') else: pass # Creamos Carpeta 'scraper_contraloria'. try: os.mkdir('scraper_contraloria') except: pass # Creamos carpeta segun la opción(REGION) dentro de 'scraper_contraloria'. try: os.mkdir(os.path.join('scraper_contraloria',region)) except: pass # Cambiamos la opcion que determina la cantidad de documentos por pagina, de '10' a '100'. dropdown = Select(driver.find_element_by_id('listaCantidadRegistros')) dropdown.select_by_visible_text('100') # Creamos listas vacias para trabajar los loops. regions = [] tipo_de_servicio = [] num_de_inf = [] entidad = [] titulo_del_informe = [] evento = [] operativo = [] n_de_p_c_p_r = [] tipo_de_responsabilidad = [] fecha_de_emision = [] fecha_de_publicacion = [] link_de_ficha_de_resumen = [] link_de_informe = [] anexos = [] # En el traspié de la página nos indica la cantidad de páginas, lo usamos para iterar el for loop. next_page = driver.find_element_by_xpath('//*[@id="lbltotalItems"]').text next_page = next_page.split('de ')[1] next_page = int(next_page) # Iteramos. try: for i in range(0,next_page,1): x = 1 zzz = '1' while zzz != 0: reg = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[1]').text] tip_de_serv = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[2]').text] num_d_inf = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[3]').text] ent = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[4]').text] tit_d_i = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[5]').text] ev = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[6]').text] op = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[7]').text] n_d_p_c_p_r = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[8]').text] t_d_r = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[9]').text] f_d_e = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[10]').text] f_d_p = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[11]').text] link_d_f_d_r = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[12]//a').get_attribute("href")] link_d_i = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[13]//a').get_attribute("href")] anx = [driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x}]/td[14]').text] try: driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{x+1}]/td[10]') except: zzz = 0 x += 1 # Llenamos las listas vacias de arriva con datos por iteración. regions += reg tipo_de_servicio += tip_de_serv num_de_inf += num_d_inf entidad += ent titulo_del_informe += tit_d_i evento += ev operativo += op n_de_p_c_p_r += n_d_p_c_p_r tipo_de_responsabilidad += t_d_r fecha_de_emision += f_d_e fecha_de_publicacion += f_d_p link_de_ficha_de_resumen += link_d_f_d_r link_de_informe += link_d_i anexos += anx # A 'region' le cambiamos los 'espacios' por 'guiones bajos' para una correcta escritura en las carpetas. region = region.replace(' ','_')###DATO EXTRA:si deseas solo el excel,comenta desde aqui hasta ....(lineas 177-247) # A 'region' Si tuviera 'puntos' seran borrados. if '.' in region: region = region.replace('.','') else: pass # A los 'número de informe' les reemplazamos caracteres extraños, para poder renombrar las carpetas y sus archivos pdf. fold = list( map(lambda x:x.replace('/', '_'), num_de_inf ) ) folde = list( map(lambda x:x.replace('\\', '_'), fold ) ) # Creamos las carpetas donde se ubicarán los pdf. for q in folde: try: os.mkdir(os.path.join('scraper_contraloria',region,q)) except: pass # Utilizamos un 'while loop' para descargar los '-resumen.pdf'. m = 1 g = 'g' while g != 0: num_d_in = driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{m}]/td[3]').text link_d_f = driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{m}]/td[12]//a').get_attribute("href") # Al los 'numero de informe' les reemplazamos caracteres extraños, para poder renombrar los '-resumen.pdf'. fold = num_d_in.replace('/','_') folde = fold.replace('\\','_') # Descargamos los 'resumen pdf', si no existe una descarga(mantenimiento de página) pasara a la siguiente descarga. try: url = link_d_f file = os.path.join(os.getcwd(),'scraper_contraloria',region,folde,folde+'-resumen.pdf') r = urllib.request.urlopen(url) f = open(file,"wb") f.write(r.read()) f.close() except: pass try: driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{m+1}]/td[3]') except: g = 0 m += 1 # Utilizamos un 'while loop' para descargar los '-informe.pdf'. m = 1 g = 'g' while g != 0: num_d_in = driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{m}]/td[3]').text link_d_i = driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{m}]/td[13]//a').get_attribute("href") # Al los 'numero de informe' les reemplazamos caracteres extraños, para poder renombrar los '-informe.pdf'. fold = num_d_in.replace('/','_') folde = fold.replace('\\','_') # Descargamos los 'informe pdf', si no existe una descarga(mantenimiento de página o etc) pasara a la siguiente descraga. try: url = link_d_i file = os.path.join(os.getcwd(),'scraper_contraloria',region,folde,folde+'-informe.pdf') r = urllib.request.urlopen(url) f = open(file,"wb") f.write(r.read()) f.close() except: pass try: driver.find_element_by_xpath(f'//*[@id="tablaResultadosUltimosInformes"]/tbody/tr[{m+1}]/td[3]') except: g = 0 m += 1 ### DATO EXTRA: ...comenta hasta aqui! para solo recibir el excel (lineas 177-246) #Damos click en 'Siguiente' para continuar con el loop en la siguiente pagina solo si ubiese. try: driver.find_element_by_xpath('//*[@id="Li_Siguiente"]/a').click() except: pass except: print('0 documentos encontrados') # Colocamos como string los números de 'número de personas con presunta responsabilidad' para centrarlos en la tabla del Excel. num_de_personas_con_presunta_responsabilidad = list( map(lambda x: x.rjust(40), n_de_p_c_p_r ) ) #Creamos el indice. indices = [] for i in range(1,len(regions)+1): indices.append(i) # Creamos el Excel. df = pd.DataFrame({'Region':regions, 'Tipo_de_Servicio':tipo_de_servicio, 'N_de_Informe':num_de_inf, 'Entidad':entidad, 'Título_del_Informe':titulo_del_informe, 'Evento':evento, 'Operativo':operativo, 'N_Personas_co_Presunta_Responsabilidad':num_de_personas_con_presunta_responsabilidad, 'Tipo_de_Responsabilidad':tipo_de_responsabilidad, 'Fecha_Emisión':fecha_de_emision, 'Fecha_Publicación':fecha_de_publicacion, 'Ficha_Resumen':link_de_ficha_de_resumen, 'Informes':link_de_informe, 'Anexos':anexos},index=indices) writer = ExcelWriter(os.path.join(os.getcwd(),'scraper_contraloria',region,f'{region}.xlsx')) df.to_excel(writer,f'{region}.xlsx') writer.save() except: driver.quit() print("Usa estas opciones con su respectivo orden:\n\n>>>scraper_contraloria('Region','Responsabilidad','Periodo')\n\ >>>scraper_contraloria('Region','Responsabilidad')\n>>>scraper_contraloria('Region')'")
Out[1]:
Usa estas opciones con su respectivo orden:
>>>scraper_contraloria('Region','Responsabilidad','Periodo')
>>>scraper_contraloria('Region','Responsabilidad')
>>>scraper_contraloria('Region')'
In [6]:
OPCIONES = ['LIMA', 'ANCASH', 'CUSCO', 'AREQUIPA', 'LA LIBERTAD', 'CAJAMARCA', 'PIURA', 'JUNIN', 'PUNO', 'AYACUCHO', 'LORETO', 'P. C. DEL CALLAO', 'LAMBAYEQUE', 'ICA', 'SAN MARTIN', 'HUANUCO', 'TACNA','HUANCAVELICA', 'UCAYALI', 'APURIMAC', 'AMAZONAS', 'TUMBES', 'MOQUEGUA', 'MADRE DE DIOS', 'PASCO'] for OPCION in OPCIONES: scraper_contraloria(OPCION,'penal') sleep(3)
(Output Hidden)
In [6]:
# scraper_contraloria('lima','administrativo') scraper_contraloria('PUNO','PENAL','2020')