Como fazer raspagem de dados da seção “As pessoas também perguntam” do Google

Um guia passo a passo para fazer raspagem de dados usando Python da seção “As pessoas também perguntam” do Google.
18 min read
How to Scrape Google's People Also Ask blog image

Neste tutorial, você aprenderá como criar um script em Python para fazer raspagem de dados da seção “As pessoas também perguntam” do Google. Isso inclui perguntas frequentes relacionadas à sua consulta de pesquisa e contém informações valiosas.

Vamos lá!

Entendendo o recurso “As pessoas também perguntam” do Google

As pessoas também perguntam” (PAA) é uma seção nos SERPs do Google (páginas de resultados de mecanismos de pesquisa) que apresenta uma lista dinâmica de perguntas relacionadas à consulta de pesquisa:

Esta seção ajuda você a explorar mais profundamente os tópicos relacionados à sua consulta de pesquisa. Lançado pela primeira vez por volta de 2015, o PAA aparece nos resultados de pesquisa como uma série de perguntas expansíveis. Quando uma pergunta é clicada, ela se expande para revelar uma breve resposta proveniente de uma página da web relevante, junto com um link para a fonte:

Abrindo os campos “As pessoas também perguntam”

A seção “As pessoas também perguntam” é atualizada com frequência e se adapta com base nas pesquisas dos usuários, oferecendo informações novas e relevantes. Novas perguntas são carregadas dinamicamente à medida que você abre os menus suspensos.

Fazendo raspagem de dados da seção “As pessoas também perguntam” do Google: guia passo a passo

Siga esta seção orientada e aprenda a criar um script em Python para fazer raspagem de dados da seção “As pessoas também perguntam” de um SERP do Google.

O objetivo final é coletar os dados contidos em cada pergunta na seção “As pessoas também perguntam” da página. Se, em vez disso, você tiver interesse em fazer raspagem de dados do Google, siga nosso tutorial sobre Raspagem de dados de SERP.

Passo 1: configuração do projeto

Antes de começar, certifique-se de ter o Python 3 instalado em sua máquina. Caso contrário, baixe-o, execute o instalador e siga o assistente de instalação.

Em seguida, use os comandos abaixo para inicializar um projeto do Python com um ambiente virtual:

mkdir people-also-ask-scraper
cd people-also-ask-scraper
python -m venv env

O diretório people-also-ask-scraper representa a pasta do projeto do seu raspador PAA do Python.

Carregue a pasta do projeto em seu IDE Python favorito. PyCharm Community Edition ou Visual Studio Code com a extensão Python são duas ótimas opções.

Na pasta do projeto, crie um arquivo scraper.py . Agora é um script em branco, mas em breve conterá a lógica de raspagem de dados:

o arquivo scraper.py na pasta do projeto

No terminal do IDE, ative o ambiente virtual. No Linux ou no macOS, execute este comando:

./env/bin/activate

Como alternativa, no Windows, execute:

env/Scripts/activate

Ótimo, agora você tem um ambiente Python para seu raspador de dados!

Passo 2: instalar o Selenium

O Google é uma plataforma que requer interação do usuário. Além disso, forjar um URL de pesquisa válido do Google pode ser um desafio. Então, a melhor maneira de trabalhar com o mecanismo de busca é dentro de um navegador.

Em outras palavras, para fazer raspagem de dados da seção “As pessoas também perguntam”, você precisa de uma ferramenta de automação do navegador. Se você não está familiarizado com esse conceito, ferramentas de automação de navegador permitem que você renderize e interaja com páginas da web dentro de um navegador controlável. Uma das melhores opções em Python é o Selenium!

Instale o Selenium executando o comando abaixo em um ambiente virtual Python ativado:

pip install selenium

O pacote selenium pip será adicionado às dependências do seu projeto. Isso pode demorar um pouco, então seja paciente.

Para obter mais detalhes sobre como usar essa ferramenta, leia nosso guia sobre raspagem de dados na web com Selenium.

Ótimo, agora você tem tudo o que precisa para começar a raspagem de dados das páginas do Google!

Etapa 3: navegar até a página inicial do Google

Importe o Selenium no scraper.py e inicialize um objeto WebDriver para controlar uma instância do Chrome no modo headless:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

# to control a Chrome window in headless mode
options = Options()
options.add_argument("--headless") # comment it while developing

# initialize a web driver instance with the
# specified options
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

O trecho acima cria uma instância do Chrome WebDriver , o objeto para controlar programaticamente uma janela do Chrome. A opção --headless configura o Chrome para ser executado no modo headless. Para fins de depuração, comente essa linha para que você possa observar as ações do script automatizado em tempo real.

Em seguida, use o método get () para se conectar à página inicial do Google:

driver.get("https://google.com/")

Não se esqueça de liberar os recursos do driver no final do script:

driver.quit()

Junte tudo e você terá:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

# to control a Chrome window in headless mode
options = Options()
options.add_argument("--headless") # comment it while developing

# initialize a web driver instance with the
# specified options
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

# connect to the Google home page
driver.get("https://google.com/")

# scraping logic...

# close the browser and free up the resources
driver.quit()

Fantástico, você está pronto para fazer raspagem de dados de sites dinâmicos!

Etapa 4: lidar com a caixa de diálogo de cookies do GDPR

Observação: se você não estiver localizado na UE (União Europeia), você pode pular esta etapa.

Execute o script scraper.py no modo headed (com interface). Isso abrirá brevemente uma janela do navegador Chrome exibindo uma página do Google antes que o comando quit () a feche. Se você estiver na União Europeia, você vera o seguinte:

A política de cookies por motivos do GDPR (usuários da UE)

A mensagem “O Chrome está sendo controlado por software de teste automatizado.” garante que o Selenium está controlando o Chrome conforme desejado.

Usuários da UE recebem uma caixa de diálogo de política de cookies por motivos de GDPR . Se esse for o seu caso, você precisará lidar com isso se quiser interagir com a página subjacente. Caso contrário, você pode pular para a etapa 5.

Abra uma página do Google no modo de navegação anônima e inspecione a caixa de diálogo de cookies do GDPR. Clique com o botão direito do mouse e escolha a opção “Inspecionar”:

Inspecionando o cookie do GDPR

Note que você pode localizar o elemento HTML da caixa de diálogo com:

cookie_dialog = driver.find_element(By.CSS_SELECTOR, "[role='dialog']")

find_element() é um método fornecido pelo Selenium para localizar elementos HTML na página por meio de diferentes estratégias. Nesse caso, usamos um seletor CSS.

Não se esqueça de importar By da seguinte forma:

from selenium.webdriver.common.by import By

Agora, foque no botão “Aceitar tudo”:

Inspecionando o botão “Aceitar tudo”

Como você pode ver, não há uma maneira fácil de selecioná-lo, pois sua classe CSS parece ter sido gerada aleatoriamente. Então, você pode coletá-lo usando uma expressão XPath que tem como alvo seu conteúdo:

accept_button = cookie_dialog.find_element(By.XPATH, "//button[contains(., 'Accept')]")

Esta instrução localizará o primeiro botão na caixa de diálogo cujo texto contém a string “Aceitar”. Para obter mais informações, leia nosso guia sobre XPath versus seletor CSS.

Veja como tudo se encaixa para lidar com a caixa de diálogo opcional de cookies do Google:

try:
    # select the dialog and accept the cookie policy
    cookie_dialog = driver.find_element(By.CSS_SELECTOR, "[role='dialog']")
    accept_button = cookie_dialog.find_element(By.XPATH, "//button[contains(., 'Accept')]")
    if accept_button is not None:
        accept_button.click()
except NoSuchElementException:
    print("Cookie dialog not present")

A instrução click() clica no botão “Aceitar tudo” para fechar a caixa de diálogo e permitir a interação do usuário. Se a caixa de diálogo da política de cookies não estiver presente,  NoSuchElementException será lançada em seu lugar. O script fará a captura e continuará.

Lembre-se de importar o NoSuchElementException:

from selenium.common import NoSuchElementException

Muito bem! Você está pronto(a) para acessar a página com a seção “As pessoas também perguntam”.

Etapa 5: enviar o formulário de pesquisa

Acesse a página inicial do Google em seu navegador e inspecione o formulário de pesquisa. Clique com o botão direito sobre ele e selecione a opção “Inspecionar”:

Inspecionando o formulário de pesquisa do Google

Esse elemento não tem classe CSS, mas você pode selecioná-lo por meio do atributo action :

search_form = driver.find_element(By.CSS_SELECTOR, "form[action='/search']")

Se você pulou a etapa 4, importe By com:

from selenium.webdriver.common.by import By

Expanda o código HTML do formulário e dê uma olhada na área de texto de pesquisa:

Olhando para a área de texto da barra de pesquisa

A classe CSS desse nó parece ter sido gerada aleatoriamente. Assim, selecione-o por meio de seu atributo aria-label . Em seguida, use o método send_keys() para digitar a consulta de pesquisa de destino:

search_textarea = search_form.find_element(By.CSS_SELECTOR, "textarea[aria-label='Search']")
search_query = "Bright Data"
search_textarea.send_keys(search_query)

Neste exemplo, a consulta de pesquisa é “Bright Data”, mas qualquer outra pesquisa é válida.

Envie o formulário para acionar uma mudança de página:

search_form.submit()

Excelente! O navegador controlado agora será redirecionado para a página do Google que contém a seção “As pessoas também perguntam”.

Se você executar o script no modo headed (com interface), isso é o que você deve ver antes do fechamento do navegador:

executando o script em um modo headed (com interface)

Observe a seção “As pessoas também perguntam” na parte inferior da captura de tela acima.

Etapa 6: selecionar o nó “As pessoas também perguntam”

Inspecione o elemento HTML “As pessoas também perguntam”:

Inspecionando o elemento HTML "As pessoas também perguntam"

Novamente, não há uma maneira fácil de selecioná-lo. Desta vez, o que você pode fazer é recuperar o elemento <div> com os atributos jscontrollerjsnamejsaction que contém um div com role=heading com o texto “As pessoas também perguntam”:

people_also_ask_div = WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((
        By.XPATH, "//div\[@jscontroller and @jsname and @jsaction\][.//div[@role='heading' and contains(., 'People also ask')]]"
    ))
)

WebDriverWait é uma classe especial do Selenium que pausa o script até que uma condição específica seja atendida na página. Acima, ele espera até 5 segundos para que o elemento HTML desejado apareça. Isso é necessário para permitir que a página carregue completamente após o envio do formulário.

A expressão XPath usada em presence_of_element_located() é complexa, mas descreve com precisão os critérios necessários para selecionar o elemento “As pessoas também perguntam”.

Não esqueça de adicionar as importações necessárias:

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

É hora de fazer a raspagem de dados da seção “As pessoas também perguntam” do Google!

Etapa 7: fazer a raspagem de dados da seção “As pessoas também perguntam”

Primeiro, inicialize uma estrutura de dados para armazenar os dados raspados:

people_also_ask_questions = []

Deve ser uma matriz, pois a seção “As pessoas também perguntam” contém várias perguntas.

Agora, inspecione a lista suspensa da primeira pergunta no nó “As pessoas também perguntam”:

Inspecionando a lista suspensa da primeira pergunta

Aqui, você pode ver que os elementos de interesse são os elementos filhos do data-sgrd="true" <div> dentro do elemento “As pessoas também perguntam”, com apenas o atributo jsname . Os últimos dois elementos filhos são usados pelo Google como espaços reservados e são preenchidos dinamicamente à medida que você abre os menus suspensos.

Selecione os menus suspensos de perguntas com a seguinte lógica:

people_also_ask_inner_div = people_also_ask_div.find_element(By.CSS_SELECTOR, "[data-sgrd='true']")
people_also_ask_inner_div_children = people_also_ask_inner_div.find_elements(By.XPATH, "./*")
for child in people_also_ask_inner_div_children:
    # if the current element is a question dropdown
    if child.get_attribute("jsname") is not None and child.get_attribute("class") == '':
        # scraping logic...

Clique no elemento para expandi-lo:

child.click() 

Em seguida, concentre-se no conteúdo dentro dos elementos da pergunta:

Inspecionando dentro dos elementos da pergunta

Observe que a pergunta está contida no <span> dentro do nó aria-expanded="true" . Faça a raspagem de dados da seguinte forma:

question_title_element = child.find_element(By.CSS_SELECTOR, "[aria-expanded='true'] span")
question_title = question_title_element.text

Em seguida, inspecione o elemento de resposta:

Inspecionando o elemento de resposta

Observe como você pode recuperá-lo coletando o texto no nó <span> com o atributo lang dentro do elemento data-attrid="wa:/description" :

question_description_element = child.find_element(By.CSS_SELECTOR, "[data-attrid='wa:/description'] span[lang]")
question_description = question_description_element.text

Em seguida, inspecione a imagem opcional na caixa de resposta:

Inspecionando a imagem opcional na caixa de resposta

Você pode obter a URL acessando o atributo src do elemento <img> com o atributo data-ilt :

try:
    question_image_element = child.find_element(By.CSS_SELECTOR, "img[data-ilt]")
    question_image = question_image_element.get_attribute("src")
except NoSuchElementException:
    question_image = None

Como o elemento de imagem é opcional, você deve envolver o código acima com um bloco try ... except . Se o nó não estiver presente na pergunta atual, find_element() gerará  NoSuchElementException. O código fará a interceptação e seguirá em frente, nesse caso,

Se você pulou a etapa 4, importe a exceção:

from selenium.common import NoSuchElementException

Por fim, inspecione a seção de origem:

Inspecionando a seção de origem

Você pode obter a URL da fonte selecionando o elemento pai <a> do elemento <h3> :

question_source_element = child.find_element(By.XPATH, ".//h3/ancestor::a")
question_source = question_source_element.get_attribute("href")

Use os dados raspados para preencher um novo objeto e adicioná-lo ao array people_also_ask_questions :

people_also_ask_question = {
  "title": question_title,
  "description": question_description,
  "image": question_image,
  "source": question_source
}
people_also_ask_questions.append(people_also_ask_question)

Muito bem! Você acabou de fazer a raspagem de dados da seção “As pessoas também perguntam” de uma página do Google.

Passo 8: exportar os dados raspados para CSV

Se você imprimir people_also_ask_questions, você verá o seguinte resultado:

[{'title': 'Is Bright Data legitimate?', 'description': 'Fast Residential Proxies from Bright Data is the industry standard for residential proxy networks. This network allows users to circumvent restrictions and bans by targeting any city, country, carrier, or ASN. It is reliable because it has over 72 million IP addresses obtained legally and an uptime of 99.99%.', 'image': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSU5S3mnWcZeQPc2KOCp55dz1zrSX4I2WvV_vJxmvf9&s', 'source': 'https://www.linkedin.com/pulse/bright-data-review-legit-scam-everything-you-need-know-bloggrand-tiakc#:~:text=Fast%20Residential%20Proxies%20from%20Bright,and%20an%20uptime%20of%2099.99%25.'}, {'title': 'What is Bright Data used for?', 'description': "Bright Data is the world's #1 web data platform, supporting the public data needs of over 22,000 organizations in nearly every industry. Using our solutions, organizations research, monitor, and analyze web data to make better decisions.", 'image': None, 'source': "https://brightdata.com/about#:~:text=Bright%20Data%20is%20the%20world's,data%20to%20make%20better%20decisions."}, {'title': 'Is Bright Data legal?', 'description': "Bright Data's platform, technology, and network (collectively, “Services”) are meant for legitimate and legal purposes only and are subject to the Bright Data Master Service Agreement.", 'image': None, 'source': "https://brightdata.com/acceptable-use-policy#:~:text=Bright%20Data's%20platform%2C%20technology%2C%20and,Bright%20Data%20Master%20Service%20Agreement."}, {'title': 'Is Bright Data free?', 'description': 'Bright Data offers four free proxy solutions to meet various needs: Anonymous Proxies: These top-performing anonymous proxies let you access websites anonymously, routing traffic through a vast Residential IP Network of over 72 million IPs, concealing your true location.', 'image': None, 'source': 'https://brightdata.com/solutions/free-proxies#:~:text=Bright%20Data%20offers%20four%20free,IPs%2C%20concealing%20your%20true%20location.'}]

Claro, isso é ótimo, mas seria muito melhor se estivesse em um formato que você pudesse compartilhar facilmente com outros membros da equipe. Então, exporte people_also_ask_questions para um arquivo CSV!

Importe o pacote csv da biblioteca padrão do Python:

import csv

Em seguida, use-o para preencher um arquivo CSV de saída com seus dados SERP:

csv_file = "people_also_ask.csv"
header = ["title", "description", "image", "source"]
with open(csv_file, "w", newline="", encoding="utf-8") as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=header)
    writer.writeheader()
    writer.writerows(people_also_ask_questions)

Finalmente! Seu script de raspagem de dados da seção “As pessoas também perguntam” está concluído.

Passo 9: juntar tudo

Seu script final scraper.py deve conter o seguinte código:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.common import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv

# to control a Chrome window in headless mode
options = Options()
options.add_argument("--headless") # comment it while developing

# initialize a web driver instance with the
# specified options
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

# connect to the Google home page
driver.get("https://google.com/")

# deal with the optional Google cookie GDPR dialog
try:
    # select the dialog and accept the cookie policy
    cookie_dialog = driver.find_element(By.CSS_SELECTOR, "[role='dialog']")
    accept_button = cookie_dialog.find_element(By.XPATH, "//button[contains(., 'Accept')]")
    if accept_button is not None:
        accept_button.click()
except NoSuchElementException:
    print("Cookie dialog not present")

# select the search form
search_form = driver.find_element(By.CSS_SELECTOR, "form[action='/search']")

# select the textarea and fill it out
search_textarea = search_form.find_element(By.CSS_SELECTOR, "textarea[aria-label='Search']")
search_query = "Bright Data"
search_textarea.send_keys(search_query)

# submit the form to perform a Google search
search_form.submit()

# wait up to 5 seconds for the "People also ask" section
# to be on the page after page change
people_also_ask_div = WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((
        By.XPATH, "//div\[@jscontroller and @jsname and @jsaction\][.//div[@role='heading' and contains(., 'People also ask')]]"
    ))
)

# where to store the scraped data
people_also_ask_questions = []

# select the question dropdowns and iterate over them
people_also_ask_inner_div = people_also_ask_div.find_element(By.CSS_SELECTOR, "[data-sgrd='true']")
people_also_ask_inner_div_children = people_also_ask_inner_div.find_elements(By.XPATH, "./*")
for child in people_also_ask_inner_div_children:
    # if the current element is a question dropdown
    if child.get_attribute("jsname") is not None and child.get_attribute("class") == '':
        # expand the element
        child.click()

        # scraping logic
        question_title_element = child.find_element(By.CSS_SELECTOR, "[aria-expanded='true'] span")
        question_title = question_title_element.text

        question_description_element = child.find_element(By.CSS_SELECTOR, "[data-attrid='wa:/description'] span[lang]")
        question_description = question_description_element.text

        try:
            question_image_element = child.find_element(By.CSS_SELECTOR, "img[data-ilt]")
            question_image = question_image_element.get_attribute("src")
        except NoSuchElementException:
            question_image = None

        question_source_element = child.find_element(By.XPATH, ".//h3/ancestor::a")
        question_source = question_source_element.get_attribute("href")

        # populate the array with the scraped data
        people_also_ask_question = {
          "title": question_title,
          "description": question_description,
          "image": question_image,
          "source": question_source
        }
        people_also_ask_questions.append(people_also_ask_question)

# export the scraped data to a CSV file
csv_file = "people_also_ask.csv"
header = ["title", "description", "image", "source"]
with open(csv_file, "w", newline="", encoding="utf-8") as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=header)
    writer.writeheader()
    writer.writerows(people_also_ask_questions)

# close the browser and free up the resources
driver.quit()

Em 100 linhas de código, você acabou de criar um raspador de dados da seção PAA!

Verifique se ele funciona ao executá-lo. No Windows, inicie o raspador com:

python scraper.py

Como alternativa, no Linux ou no macOS, execute:

python3 scraper.py

Aguarde a execução do raspador terminar, e um arquivo people_also_ask.csv aparecerá no diretório raiz do seu projeto. Abra e você verá:

Exemplo de um arquivo CSV incluindo os dados raspados da seção "As Pessoas Também Perguntam"

Parabéns, missão cumprida!

Conclusão

Neste tutorial, você aprendeu o que é a seção “As pessoas também perguntam” nas páginas do Google, os dados que ela contém e como fazer raspagem de dados usando Python. Como você aprendeu aqui, criar um script simples para extrair dados automaticamente requer apenas algumas linhas de código Python.

Embora a solução apresentada funcione bem para projetos pequenos, ela não é prática para raspagem de dados em grande escala. O problema é que o Google tem algumas das tecnologias anti-bots mais avançadas do setor. Portanto, ele pode bloquear você com CAPTCHAs ou proibições de IP. Além disso, escalar esse processo em várias páginas aumentaria os custos de infraestrutura.

Isso significa que é impossível fazer raspagem de dados do Google de forma eficiente e confiável? De jeito nenhum! Você simplesmente precisa de uma solução avançada que resolva esses desafios, como a API de pesquisa do Google da Bright Data.

A API de pesquisa do Google fornece um endpoint (ponto de extremidade) para recuperar dados das páginas do SERP do Google, incluindo a seção “As pessoas também perguntam”. Com uma simples chamada de API, você pode obter os dados desejados no formato JSON ou HTML. Veja como começar a usar na documentação oficial.

Inscreva-se agora e comece seu teste gratuito!

Não é necessário cartão de crédito