Como fazer scraping no eBay em 2024: Um guia para iniciantes

Python, Como fazer, 21 de novembro de 20245 minutos de leitura

O eBay é um dos maiores mercados online do mundo, albergando milhões de produtos de várias categorias. A recolha de dados do eBay pode ser valiosa para tarefas como:

  • Comparação de preços
  • Análise do mercado
  • Acompanhamento das tendências dos produtos

Neste guia, mostraremos como criar um script Python simples para pesquisar uma palavra-chave, extrair detalhes do produto, como título, preço, moeda, disponibilidade, resenhas e classificações, e salvar os dados em um arquivo CSV. Este tutorial é ótimo para principiantes que querem aprender a fazer web scraping da forma correta, com dicas sobre como respeitar os termos de serviço e utilizar proxies de forma responsável.

Não gostou da explicação? Aqui está o código completo

Se está apenas à procura da implementação completa, aqui está o script Python completo para extrair detalhes de produtos do eBay usando proxies. Copie e cole-o no seu ambiente para começar:

import re
import csv
import time

import requests
from bs4 import BeautifulSoup

proxies = {
    "http": "http://username:[email protected]:6060",
    "https": "http://username:[email protected]:6060",
}

def get_product_information(product_url) -> dict:
    r = requests.get(product_url, proxies=proxies)
    soup = BeautifulSoup(r.text, features="html.parser")

    product_title = soup.find("h1", {"class": "x-item-title__mainTitle"}).text
    product_price = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[-1]
    currency = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[0]

    # locate the element that holds quanity number of product
    quantity_available = soup.find("div", {"class":"x-quantity__availability"})
    if quantity_available is not None:
        # Using regex check if we can locate the strings that holds this number
        regex_pattern = r"\d+\savailable"
        if re.search(regex_pattern, quantity_available.text) is not None:
            quantity_available = re.search(regex_pattern, quantity_available.text).group()
            # After string is located we extract the number by splitting it by space and selecting the first element.
            quantity_available = quantity_available.split(" ")[0]
        else:
            quantity_available = "NA"

    total_reviews = soup.find("span", {"class":"ux-summary__count"})
    if total_reviews is not None:
        total_reviews = total_reviews.text.split(" ")[0]
    else:
        total_reviews = "NA"

    rating = soup.find("span", {"class":"ux-summary__start--rating"})
    if rating is not None:
        rating = rating.text
    else:
        rating = "NA"

    product_info = {
        "product_url": product_url,
        "title": product_title,
        "product_price": product_price,
        "currency": currency,
        "availability": quantity_available,
        "nr_reviews": total_reviews,
        "rating": rating
    }

    return product_info

def save_to_csv(products, csv_file_name="products.csv"):

    # Write the list of dictionaries to a CSV file
    with open(csv_file_name, mode='w', newline='') as csv_file:
        # Create a csv.DictWriter object
        writer = csv.DictWriter(csv_file, fieldnames=products[0].keys())

        # Write the header (keys of the dictionary)
        writer.writeheader()

        # Write the rows (values of the dictionaries)
        writer.writerows(products)

    print(f"Data successfully written to {csv_file_name}")

def main(keyword_to_search: str):
    products = []

    r = requests.get(f"https://www.ebay.com/sch/i.html?_nkw={keyword_to_search}", proxies=proxies)

    soup = BeautifulSoup(r.text, features="html.parser")
    for item in soup.find_all("div", {"class": "s-item__info clearfix"})[2::]:
        item_url = item.find("a").get("href")

        product_info: dict = get_product_information(item_url)
        print(product_info)
        # Adding a 1-second delay between requests to avoid overloading the server and reduce the risk of being blocked
        time.sleep(2)

        products.append(product_info)
    # save data to csv
    save_to_csv(products)


if __name__ == '__main__':
    keywords = "laptop bag"
    main(keywords)

Não se esqueça de atualizar a variável proxies com um novo nome de utilizador e palavra-passe antes de os utilizar.

Como é que vamos fazer scraping no eBay

O nosso método simplifica o processo, centrando-se em quatro funções-chave:

  • Pesquisar uma palavra-chave: Descubra produtos introduzindo um termo de pesquisa (por exemplo, "malas para computador portátil") para obter itens relevantes.
  • Extração de URLs de produtos: Recolher URLs de produtos listados na primeira página do resultado da pesquisa para simplificar a recolha de dados.
  • Extração de informações sobre o produto: Para cada URL de produto, navegaremos para a página do produto para obter informações vitais.
  • Guardar dados: Guarde os dados extraídos num ficheiro CSV para um acesso e análise eficientes.

Pré-requisitos

Começar com as ferramentas certas é crucial. É necessário:

Instalar o Python:

Configure seu ambiente de desenvolvimento:

  • Selecione o diretório onde pretende colocar este projeto. Configure um ambiente virtual para manter as dependências limpas e isoladas.
mkdir ebay_scraping
cd ebay_scraping
python -m venv venv
source env/bin/activate # No Windows use: venv\Scripts\activate
pip install requests bs4

Configuração de proxies:

Neste exemplo, utilizaremos proxies residenciais Proxyscrape rotativos para manter o anonimato e proteger o ip privado de ser colocado na lista negra.

Explicação do guião

Passo 1: Importar bibliotecas e proxies

Começamos por importar as bibliotecas necessárias para este projeto de recolha de dados da Web, que incluem:

  • CSV: este módulo fornece classes para ler e escrever dados tabulares em formato CSV. Permite aos programadores escreverem facilmente dados no formato preferido do Excel ou lerem dados de ficheiros gerados pelo Excel sem conhecerem os detalhes precisos do formato CSV.
  • Requests (Pedidos): este módulo permite-lhe enviar pedidos HTTP utilizando Python.
  • O BeautifulSoup4 é um poderoso analisador de html concebido para extrair a informação de que necessita de uma estrutura html.

Importações necessárias:

importar csv
importar hora
importar pedidos
from bs4 import BeautifulSoup

Configuração de proxy:

Para manter o seu ip privado, minimizando assim as chances de ter o seu ip na lista negra de sites específicos, recomenda-se realizar atividades de raspagem da web sob o escudo de proxies, como mencionado acima, estaremos usando Proxyscrape Residential Proxies rotativos para este tutorial, mas você pode usar outros proxies ou nenhum proxies.

proxies = {
   "http": "http://username:[email protected]:6060",
   "https": "http://username:[email protected]:6060",
}

Passo 2: Obter resultados de pesquisa

Comecemos por explicar o processo de pesquisa que vamos utilizar neste tutorial. Vamos consultar o URL do eBay com a palavra-chave "laptop bag" (mala para portátil), como mostra esta imagem:

Utilizaremos o URL consultado para enviar um pedido com pedido.get(). Quando recebermos uma resposta, analisaremos o conteúdo HTML usando BeautifulSoup (bs4) para extrair o URL de cada produto. A imagem abaixo mostra onde o URL de cada produto está localizado no HTML.

A ligação do produto encontra-se numa <div> com o elemento classe s-item__info clearfix. Para extrair estas ligações, utilizamos BeautifulSoup (bs4) para procurar todos os <div> elementos com esta classe específica. Depois de localizarmos estes elementos, iteramos através de cada um deles para encontrar <a> e extrair os elementos href que contém o URL do produto.

def main(keyword_to_search: str):
   products = []

   r = requests.get(f"https://www.ebay.com/sch/i.html?_nkw={keyword_to_search}", proxies=proxies)

   soup = BeautifulSoup(r.text, features="html.parser")
   for item in soup.find_all("div", {"class": "s-item__info clearfix"})[2::]:
       item_url = item.find("a").get("href")

       product_info: dict = get_product_information(item_url)
		# Adding a 1-second delay between requests to avoid overloading the server and reduce the risk of being blocked
       time.sleep(1)

       products.append(product_info)
   # save data to csv
   save_to_csv(products)

Etapa 3: Extrair informações sobre o produto

Apresentando o get_product_information função. Esta função recebe um URL de produto como entrada, envia um pedido para esse URL e, em seguida, utiliza o BeautifulSoup (bs4) para analisar as informações do produto utilizando regras específicas e padrões regex.

def get_product_information(product_url) -> dict:
   r = requests.get(product_url, proxies=proxies)
   soup = BeautifulSoup(r.text, features="html.parser")

   product_title = soup.find("h1", {"class": "x-item-title__mainTitle"}).text
   product_price = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[-1]
   currency = soup.find("div", {"class": "x-price-primary"}).text.split(" ")[0]

   # locate the element that holds quanity number of product
   quantity_available = soup.find("div", {"class":"x-quantity__availability"})
   if quantity_available is not None:
       # Using regex check if we can locate the strings that holds this number
       regex_pattern = r"\d+\savailable"
       if re.search(regex_pattern, quantity_available.text) is not None:
           quantity_available = re.search(regex_pattern, quantity_available.text).group()
           # After string is located we extract the number by splitting it by space and selecting the first element.
           quantity_available = quantity_available.split(" ")[0]
       else:
           quantity_available = "NA"

   total_reviews = soup.find("span", {"class":"ux-summary__count"})
   if total_reviews is not None:
       total_reviews = total_reviews.text.split(" ")[0]
   else:
       total_reviews = "NA"

   rating = soup.find("span", {"class":"ux-summary__start--rating"})
   if rating is not None:
       rating = rating.text
   else:
       rating = "NA"

   product_info = {
       "product_url": product_url,
       "title": product_title,
       "product_price": product_price,
       "currency": currency,
       "availability": quantity_available,
       "nr_reviews": total_reviews,
       "rating": rating
   }

   return product_info

Por fim, organizamos as entidades de produto analisadas num dicionário, que é devolvido pela função.

Passo 4: Guardar resultados

É hora de armazenar esses resultados em um arquivo CSV usando a função nativa do Python csv biblioteca. O guardar_para_csv(produtos) A função aceita produtos como entrada, que é uma lista de dicionários que contêm detalhes do produto, como descrito anteriormente. Estes dados são depois guardados num ficheiro CSV com o nome do nome_do_ficheiro_csv que, por predefinição, é "products.csv".

def save_to_csv(products, csv_file_name="products.csv"):

   # Write the list of dictionaries to a CSV file
   with open(csv_file_name, mode='w', newline='') as csv_file:
       # Create a csv.DictWriter object
       writer = csv.DictWriter(csv_file, fieldnames=products[0].keys())

       # Write the header (keys of the dictionary)
       writer.writeheader()

       # Write the rows (values of the dictionaries)
       writer.writerows(products)

   print(f"Data successfully written to {csv_file_name}")

Conclusão

Neste tutorial, demonstramos como fazer scraping do eBay criando um script Python que pesquisa uma palavra-chave, extrai detalhes do produto e salva os dados em um arquivo CSV. Esse processo destaca técnicas essenciais de raspagem, como manipulação de elementos HTML, uso de proxies para anonimato e respeito às práticas éticas de raspagem. Este script pode ser melhorado incorporando a funcionalidade de paginação e a capacidade de processar várias palavras-chave.

Lembre-se sempre de fazer scraping de forma responsável, aderir aos termos de serviço do site e usar ferramentas como limitação de taxa para evitar interrupções. Para tornar as suas tarefas de raspagem mais fiáveis e eficientes, considere explorar os nossos serviços de proxy de alta qualidade em ProxyScrape. Quer necessite de proxies residenciais, de centros de dados ou móveis, temos tudo o que precisa. Confira nossas ofertas para levar seus projetos de raspagem da web para o próximo nível!

Boa raspagem!