Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Problemas com Web Scraping

Boa tarde pessoal, crie essa função para fazer um scraping no preço de alguns brinquedos:

def obtem_produtos():
  response = urlopen('https://www.rihappy.com.br/brinquedos/quebra-cabecas')
  html = response.read().decode('utf-8')
  soup = BeautifulSoup(html, 'html.parser')
  div = soup.find('div', {'class' : 'it-shelf-new baby-departamento n24colunas'})
  produtos = []
  for row in div.findAll('li'):
    produto = row.find('a')
    produtos.append(produto)
  return produtos

obtem_produtos()

porém alguns problemas estão surgindo. O meu objetivo é obter o nome e o preço dos produtos. Eu tentei obter o nome colocandoproduto = row.find('a')['data-nome'] mas isso não funciona. Isso já seria uma primeira dúvida (Por que não funciona ?). Dado que essa alternativa não funcionou, tentei obter os dados desejados pela lista gerada pela função acima. Assim, criei um objeto chamado lista lista = obtem_produto(). Ao fazer lista[0]['data-nome'] consigo obter o nome do primeiro produto . Então tentei iterar essa lista para obter os demais nomes da seguinte forma:

produtos =[]

e depois

for i in range(len(lista)): produtos.append(lista[i]['data-nome']

só que ao fazer isso obtenho o erro:

TypeError: 'NoneType' object is not iterable

Alguém sabe como devo proceder ?

1 resposta
solução!

Olá Miguel,

Esse erro está aparecendo porque alguns dos li selecionados não tem a tag a dentro, alguns li tem a tag a e vai dar certo pegar o data-nome corretamente mas entre eles alguns row.find('a') não vão retornar nada, assim você não pode acessar o ['data-nome'] de um nada.

O que você deve fazer então é melhorar o filtro (buscar por uma classe mais específica, etc.) ou fazer um teste para verificar se a tag selecionada possui o atributo que você quer:

from urllib.request import urlopen
from bs4 import BeautifulSoup

def obtem_produtos():
  response = urlopen('https://www.rihappy.com.br/brinquedos/quebra-cabecas')
  html = response.read().decode('utf-8')
  soup = BeautifulSoup(html, 'html.parser')
  div = soup.find('div', {'class' : 'it-shelf-new baby-departamento n24colunas'})
  produtos = []
  teste = []

  for row in div.findAll('li'):
    produto = row.find('a', attrs={"class": "productIdInRel"})
    # Verifica se foi encontrado um produto e se ele tem o 'data-nome'
    if produto != None and produto.has_attr('data-nome'):
        produtos.append(produto['data-nome'])
  return produtos

obtem_produtos()

Resultado:

['Quebra-Cabeça Leonardo Da Vinci - Monalisa - 1000 peças - Grow',
 'Quebra-Cabeça - Personagens Disney - 30 Peças - 2018 - Grow',
 'Quebra-Cabeça - 48 Peças - Conhecendo o Mundo - Toyster',
 'Quebra Cabeça - 500 Peças - Séries de Televisão - Friends - Grow',
 'Quebra-Cabeça - Progressivo - PJ Masks - 12, 20, 30 Peças - Grow',
 'Conjunto de Quebra - Cabeças - 3 puzzles - Patrulha Canina - 2019 - Grow',
 'Quebra-Cabeça - Harry Potter - 150 Peças - Grow',
 'Quebra-Cabeça - Harry Potter - Panorama - 350 peças - Grow',
 'Quebra-Cabeça - Vivaldi - As Quatro Estações - 4000 peças - Grow',
 'Quebra-Cabeça - 200 Peças - LOL - Grow',
 'Quebra-Cabeça - 100 Peças - LOL - Grow',
 'Quebra-Cabeça Progressivo - Meu Primeiro Quebra-Cabeça - 2 - 3 e 4 Peças - Toyster',
 'Quebra-Cabeça - 100 Peças - Reino de Doces - Toyster',
 'Quebra-Cabeça - 200 Peças - Disney - Star Wars - Episódio IX - toyster',
 'Quebra-Cabeça - 500 Peças - Rotterdam - Grow',
 'Quebra-Cabeça - Luccas Neto - 60 Peças - Grow',
 'Quebra-Cabeça  - Reino Dos Unicórnios - 100 Peças - Toyster',
 'Quebra-Cabeça - 60 Peças - Unicórnio - Grow',
 'Jogo de Quebra-cabeça - 30 peças - Patrulha Canina - Modelo 2 - Grow',
 'Quebra Cabeça - Alfabeto dos Animais - 60 Peças - Toyster',
 'Quebra-Cabeça Grandão - 120 Peças - Disney - Marvel - Spider-Man - Toyster',
 'Separador de Peças de Quebra-Cabeça - 6 bandejas - Grow',
 'Quebra-Cabeça - Dinossauros - 100 Peças - Grow',
 'Quebra-Cabeça - Castelo de Neschwanstein - 1000 Peças - Grow']

Com isso já traz os nomes corretamente, falta apenas pegar o preço que pode ser feito com algo parecido. Se tiver alguma dúvida ou problema para adicionar a parte do preço é só falar!