Ajuda raspagem de dados | Site de notícias - Selenium

Oi, tudo bem?

Preciso de ajuda no uso de Selenium + Python + Beautifulsoup.

Essa versão do código onde o que é encontrado na página inicial é raspado e armazenado em um json funciona:

from selenium import webdriver
import time
from bs4 import BeautifulSoup
import pandas as pd
import os

lista_noticias = []

navegador = webdriver.Chrome()

url = 'https://www.globo.com/busca/?q=Seguran%C3%A7a%20da%20Informa%C3%A7%C3%A3o'
navegador.get(url)

site = BeautifulSoup(navegador.page_source, 'html.parser')

div_noticia = site.find_all('li', attrs={'class':'widget widget--card widget--info'})   

for noticia in div_noticia:

     titulo = noticia.find('div', attrs={'class':'widget--info__title product-color'}).text
    link = noticia.find('a')['href']
     site_publicacao = noticia.find('div', attrs={'class':'widget--info__header'}).text
     subtitulo = noticia.find('p', attrs={'class':'widget--info__description'}).text
     data_publicacao = noticia.find('div', attrs={'class': 'widget--info__meta'}).text


     lista_noticias.append([titulo,link,site_publicacao,subtitulo,data_publicacao])

 noticias = pd.DataFrame(lista_noticias, columns=['titulo', 'link', 'site_publicacao','subtitulo','data_publicacao'])


  nome_arquivo = "noticias.json"
  caminho_arquivo = os.path.join(os.path.dirname(__file__), nome_arquivo)

  noticias.to_json(caminho_arquivo, orient='records', lines=True)

  print("Arquivo JSON salvo:", caminho_arquivo)**

Porém quando adiciono o Selenium para lidar com o botão de ‘Veja mais’ da página de pesquisa, mesmo com os elementos html corretos, o código não funciona.

from selenium import webdriver
import time
from bs4 import BeautifulSoup
import pandas as pd
import os

lista_noticias = []

navegador = webdriver.Chrome()

url = 'https://www.globo.com/busca/?q=Seguran%C3%A7a%20da%20Informa%C3%A7%C3%A3o'
navegador.get(url)

 while True:
     try:
        botao_veja_mais = navegador.find_elements_by_xpath('//*[@id="content"]/div/div/div/a')
        botao_veja_mais.click()
        time.sleep(5)
        print("Clicou em 'Veja mais'.")
    except:
        print("Não há mais botões 'Veja mais'.")
        break
site = BeautifulSoup(navegador.page_source, 'html.parser')

div_noticia = site.find_all('li', attrs={'class':'widget widget--card widget--info'})   

for noticia in div_noticia:
    titulo = noticia.find('div', attrs={'class':'widget--info__title product-color'}).text
    link = noticia.find('a')['href']
    site_publicacao = noticia.find('div', attrs={'class':'widget--info__header'}).text
    subtitulo = noticia.find('p', attrs={'class':'widget--info__description'}).text
    data_publicacao = noticia.find('div', attrs={'class': 'widget--info__meta'}).text


    lista_noticias.append([titulo, link, site_publicacao, subtitulo, data_publicacao])


noticias = pd.DataFrame(lista_noticias, columns=['titulo', 'link', 'site_publicacao', 'subtitulo', 'data_publicacao'])


nome_arquivo = "noticias.json"
caminho_arquivo = os.path.join(os.path.dirname(__file__), nome_arquivo)

noticias.to_json(caminho_arquivo, orient='records', lines=True)

print("Arquivo JSON salvo:", caminho_arquivo)

navegador.quit()**

Todas as bibliotecas estão instaladas corretamente. Alguém sabe como resolver esse problema?

Fiz algumas mudanças no código que parecem ter corrigido o problema.

A primeira delas foi usar ActionChains pra simular o clique da tecla END no teclado, pra rolar até o final da página e tonar o botão “Veja mais” visível e, portanto, clicável. O próprio ato de ir ao final da página parece ser suficiente para que sejam carregadas mais notícias, então talvez esse procedimento de clicar no botão não seja necessário, ou pode ser melhorado.

Outra mudança que fiz (mas esta depende de qual versão do Selenium está instalada - 4.9.1 no meu caso) foi mudar a linha que encontra o botão para ser clicado. Em alguma versão do Selenium o método “find_elements_by_xxxx” foi trocado para um mais genérico find_element()

Por fim, troquei o Except de propósito geral por um específico, para tratar do erro que ocorre ao não encontrar o botão desejado.

Segue o código completo com as mudanças:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

import time
from bs4 import BeautifulSoup
import pandas as pd
import os

lista_noticias = []

navegador = webdriver.Firefox()
ac = ActionChains(navegador)

url = 'https://www.globo.com/busca/?q=Seguran%C3%A7a%20da%20Informa%C3%A7%C3%A3o'
navegador.get(url)

while True:
    try:
        for i in range(5):
            ac.send_keys(Keys.END)
            ac.perform()
            time.sleep(1)
        botao_veja_mais = navegador.find_element(By.CSS_SELECTOR, 'a.fundo-cor-produto')
        botao_veja_mais.click()
        time.sleep(5)
        print("Clicou em 'Veja mais'.")
    except NoSuchElementException as not_found:
        print("Não há mais botões 'Veja mais'.")
        break
site = BeautifulSoup(navegador.page_source, 'html.parser')

div_noticia = site.find_all('li', attrs={'class':'widget widget--card widget--info'})   

for noticia in div_noticia:
    titulo = noticia.find('div', attrs={'class':'widget--info__title product-color'}).text
    link = noticia.find('a')['href']
    site_publicacao = noticia.find('div', attrs={'class':'widget--info__header'}).text
    subtitulo = noticia.find('p', attrs={'class':'widget--info__description'}).text
    data_publicacao = noticia.find('div', attrs={'class': 'widget--info__meta'}).text


    lista_noticias.append([titulo, link, site_publicacao, subtitulo, data_publicacao])


noticias = pd.DataFrame(lista_noticias, columns=['titulo', 'link', 'site_publicacao', 'subtitulo', 'data_publicacao'])


nome_arquivo = "noticias.json"
caminho_arquivo = os.path.join(os.path.dirname(__file__), nome_arquivo)

noticias.to_json(caminho_arquivo, orient='records', lines=True)

print("Arquivo JSON salvo:", caminho_arquivo)

navegador.quit()

A última coisa que percebi foi que a página do G1 tem uma certa paginação, então talvez o selenium não seja necessário para acessar as notícias passadas. Basta mudar o parâmetro page na URL a seguir:
https://www.globo.com/busca/?q=Seguran%C3%A7a+da+Informa%C3%A7%C3%A3o&page=9

Obrigado! Ajudou demais <3