def get_reportaje(self, url_pagina): """ Obtiene un reportaje desde rbb.cl, se necesita una funcion completamente diferente porque se usa un layout distinto. Args: url_pagina (str): Url al reportaje Returns: dict: Reportaje - titulo (str): Titulo del reportaje - contenido (str): Texto plano extraido del reportaje - link (str): URL al reportaje. """ try: logger.info(f'Obteniendo reportaje desde: {url_pagina}') page = requests.get(url_pagina) soup = BeautifulSoup(page.content, 'lxml') reportaje = {'link': url_pagina} # Obtener Titulo scripts = soup.find_all('script') for i, _s in enumerate(scripts): if 'title_to_sanitize' in _s.text: buscar_titulo = re.search("'.*'", _s.text) titulo = buscar_titulo.group(0).replace('\'', '') reportaje['titulo'] = titulo ## # Obtener Contenido extracto = 'EXTRACTO: ' + soup.find('p', {'id': 'extracto'}).text noticia_ps = soup.find('div', { 'class': 'noticia-contenido' }).find_all('p') parrafos = [] for _p in noticia_ps: _id = _p.get('id') or _p.get('class') if not _id: if _p.text != '': parrafos.append(_p.text) reportaje['contenido'] = '\n'.join((extracto, *parrafos)) ## except Exception as exc: logger.error(traceback.format_exc()) return None return reportaje
def get_lista_noticias_dia(self, url_nacional=None, url_politica=None, fecha=datetime.now()): """ Obtiene la lista de noticias desde las secciones de politica y nacional de latercera.com Args: url_politica (str): URL a seccion de Politica. url_nacional (str): URL a seccion Nacional. fecha (datetime): Fecha de la que se extrae el dia y el mes para obtener las noticias. Returns: lista_a_noticias (list): Lista de links a las noticias del dia. """ if not url_nacional: url_nacional = self.url_nacional if not url_politica: url_politica = self.url_politica mes, dia = fecha.month, fecha.day lista_a_noticias = [] secciones = [url_nacional, url_politica] logger.info(f'Obteniendo Links a Noticias para dia {fecha}') for seccion in secciones: buscando = True iniciando = True pagina = 1 while buscando: url_pagina = seccion + str(pagina) logger.info(f'Pagina: {url_pagina}') page = requests.get(url_pagina) soup = BeautifulSoup(page.content, 'lxml') lista_noticias = soup.find_all('article', {'class': 'border-bottom-1 archive-article'}) for a_noticia in lista_noticias: _fecha = a_noticia.find('small', {'class': 'time-ago'}).text.strip() noticia = {'link': a_noticia.a['href'], 'fecha': datetime.strptime(_fecha, '%d/%m/%Y %I:%M %p')} datetime_noticia = noticia['fecha'] logger.info(noticia) if datetime_noticia.month == mes and datetime_noticia.day == dia: lista_a_noticias.append(noticia) iniciando = False else: if not iniciando: buscando = False break pagina += 1 logger.info('ok') return lista_a_noticias
def get_noticia(self, url_pagina: str): """ Obtiene una noticia regular desde latercera.com. Args: url_pagina (str): Url de Noticia a obtener. Returns: dict: Noticia: - titulo (str): Titulo de la noticia. - contenido (str): Contenido de la noticia. - link (str): URL a la noticia. """ try: logger.info(f'Obteniendo noticia desde: {url_pagina}') page = requests.get(url_pagina) soup = BeautifulSoup(page.content, 'lxml') noticia = {'link': url_pagina} # Titulo Noticia titulo = soup.find('h1', {'class': 'm-top-30'}).text titulo = str(titulo).strip() noticia['titulo'] = titulo contenido = [] # Bajada bajada = soup.find('div', {'class': 'bg-gray bajada-art'}) if bajada: bajada = bajada.h2.text contenido.append(bajada) # Contenido Nota primer_elemento = soup.find('div', {"id": "ambideXtro"}).contents[0] for elemento in primer_elemento.find_next_siblings(): if elemento != '\n' and elemento.name in ['h1', 'h2', 'p']: contenido.append(elemento.text) noticia['contenido'] = '\n'.join(contenido) return noticia except Exception as exc: logger.error(exc) return None
def get_regular(self, url_pagina): """ Obtiene una noticia regular desde rbb.cl. Args: url_pagina (str): Url de Noticia a obtener. Returns: dict: Noticia: - titulo (str): Titulo de la noticia. - contenido (str): Contenido de la noticia. - link (str): URL a la noticia. """ try: logger.info(f'Obteniendo noticia desde: {url_pagina}') page = requests.get(url_pagina) soup = BeautifulSoup(page.content, 'lxml') noticia = {'link': url_pagina} # Titulo Noticia titulo = soup.find('h1', {'id': 'titulo-nota'}).text titulo = str(titulo).strip() noticia['titulo'] = titulo # Contenido Nota parrafos = soup.find('div', { "class": "contenido-nota" }).find_all('p') contenido = [] for parrafo in parrafos: contenido.append(parrafo.text.strip()) noticia['contenido'] = '\n'.join(contenido) except Exception: logger.error(traceback.format_exc()) return None return noticia
def get_lista_noticias_dia(self, url_nacional_paginacion=None, fecha=datetime.now()): """ Obtiene la lista de noticias desde la seccion nacional de rbb en un determinado día. Args: url_nacional_paginacion (list): Lista que funciona como template para recorrer la seccion paginada. [0] = inicio del template <- Numero de la pagina -> [1] = fin del template fecha (datetime): Fecha de la que se extrae el dia y el mes para obtener las noticias Returns: lista_a_noticias (list): Lista de links a las noticias del dia. """ mes, dia = fecha.month, fecha.day lista_a_noticias = [] buscando = True iniciando = True pagina = 0 print('Obteniendo Links a Noticias.') while buscando: if not url_nacional_paginacion: url_nacional_paginacion = self.url_template_paginacion url_pagina = f'{url_nacional_paginacion[0]}{pagina}{url_nacional_paginacion[1]}' logger.info(f'Pagina: {url_pagina}') page = requests.get(url_pagina) soup = BeautifulSoup(page.content, 'lxml') lista_noticias = soup.find('ul', { 'id': 'results-list' }).find_all('li') for a_noticia in lista_noticias: _fecha = a_noticia.a.span.text noticia = { 'link': a_noticia.a['href'], 'fecha': datetime.strptime(_fecha, '%d/%m/%Y %H:%M') } datetime_noticia = noticia['fecha'] logger.info(noticia) if datetime_noticia.month == mes and datetime_noticia.day == dia: lista_a_noticias.append(noticia) iniciando = False else: if not iniciando: buscando = False break pagina += 1 logger.info('ok') return lista_a_noticias
def agregar_noticias(): logger.info('Ejecutando Script.') fuente = obtener_fuente() scrapper = ScrapperRBB() lista_legisladores = Legislador.query.filter_by(buscar_noticias=True).all() # Obtener el dia anterior (de manera correcta). ahora = datetime.now() fecha = datetime(ahora.year, ahora.month, ahora.day) - timedelta(days=1) for intento in range(3): lista_a_noticias_dia = scrapper.get_lista_noticias_dia(fecha=fecha) if lista_a_noticias_dia: break else: sleep(15) noticias = [] for a_noticia in lista_a_noticias_dia: _noticia = None for intento in range(3): link = a_noticia['link'] if 'reportajes' in link: _noticia = scrapper.get_reportaje(link) elif '/noticias/deportes/' in link: _noticia = scrapper.get_deporte(link) else: _noticia = scrapper.get_regular(link) if _noticia: break if _noticia: noticia = Noticia( _noticia['titulo'], _noticia['link'], contenido_texto=_noticia['contenido'], fecha=a_noticia['fecha'], ) noticia.fuente = fuente legisladores_encontrados = [] for legislador in lista_legisladores: if buscar_nombres_texto(noticia.contenido_texto, legislador.primer_nombre, legislador.segundo_nombre, legislador.primer_apellido, legislador.segundo_apellido): legisladores_encontrados.append(legislador) if len(legisladores_encontrados) > 0: noticia.legisladores = legisladores_encontrados noticias.append(noticia) logger.info('Noticias con Legisladores Encontradas:') for n in noticias: print(f'{n.titulo} - {n.legisladores}') logger.info('Total Noticias Encontradas = ' + str(len(noticias))) db.session.remove() # Reiniciar session for n in noticias: db.session.add(n) db.session.commit() logger.info('Fin Agregado')