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

Erro Dict has no attribute

Pessoal, estou tentando rodar a versão total do código:

from urllib.request import urlretrieve, urlopen
from bs4 import BeautifulSoup
import pandas as pd

# Acessando e tratando o html
url = 'https://alura-site-scraping.herokuapp.com/index.php'

req = Request(url)
response = urlopen(req)
html = response.read()
html = html.decode('UTF-8')

soup = BeautifulSoup(html)

# Declarando a variável cards (lista que armazenará todos os anúncios)

card = []

# Obtendo as tags de interesse:
anuncios = soup.find('div', id="container-cards").findAll('div', class_='card')

# Coletando as informações dos cards:

for anuncio in anuncios:

    # valor do carro:

    card = {}

    valor_anuncio = anuncio.find('p', {'class':'txt-value'}).getText()

    card['value'] = valor_anuncio

    # informações do carro:
    infos = anuncio.find('div', {'class':'body-card'}).findAll('p')
    for info in infos:
        card[info.get('class')[0].split('-')[-1]] = info.get_text()

    # acessórios do carro:
    acessorios = anuncio.find('ul', {'class': 'lst-items'}).findAll('li')
    lista_acessorios = []
    for li in acessorios:
        lista_acessorios.append(li.getText().replace('► ',''))
    lista_acessorios.pop()
    card['acessorios'] = lista_acessorios
    card

    # salvando a foto do carro:
    image = anuncio.find('div', {'class':'image-card'}).img
    urlretrieve(image.get('src'), './output/img/' + image.get('src').split('/')[-1])

    anuncios.append(card)

Porém, ele está me devolvendo o seguinte erro:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-76-b28d51f435d1> in <module>
     28     card = {}
     29 
---> 30     valor_anuncio = anuncio.find('p', {'class':'txt-value'}).getText()
     31 
     32     card['value'] = valor_anuncio

AttributeError: 'dict' object has no attribute 'find'
1 resposta
solução!

Olá Leonardo,

O que está acontecendo é que nessa parte "for anuncio in anuncios:" você está acessando os itens de anuncios, mas logo no final você está adicionando mais itens em anuncios na parte "anuncios.append(card)"

Então você acaba com itens de tipos diferentes misturados dentro de anuncios, e em algum momento o código tenta executar o .find() em um dos cards que você criou e inseriu em anuncios.

Para corrigir é só mudar a lista onde você guarda os cards, cria uma nova lista antes do for "cards = []" por exemplo e no final do for troca "anuncios.append(card)" por cards.append(card)

from urllib.request import urlretrieve, urlopen, Request
from bs4 import BeautifulSoup
import pandas as pd

# Acessando e tratando o html
url = 'https://alura-site-scraping.herokuapp.com/index.php'

req = Request(url)
response = urlopen(req)
html = response.read()
html = html.decode('UTF-8')

soup = BeautifulSoup(html)

# Declarando a variável cards (lista que armazenará todos os anúncios)

card = []

# Obtendo as tags de interesse:
anuncios = soup.find('div', id="container-cards").findAll('div', class_='card')
cards = []

# Coletando as informações dos cards:

for anuncio in anuncios:

    # valor do carro:

    card = {}

    valor_anuncio = anuncio.find('p', {'class':'txt-value'}).getText()

    card['value'] = valor_anuncio

    # informações do carro:
    infos = anuncio.find('div', {'class':'body-card'}).findAll('p')
    for info in infos:
        card[info.get('class')[0].split('-')[-1]] = info.get_text()

    # acessórios do carro:
    acessorios = anuncio.find('ul', {'class': 'lst-items'}).findAll('li')
    lista_acessorios = []
    for li in acessorios:
        lista_acessorios.append(li.getText().replace('► ',''))
    lista_acessorios.pop()
    card['acessorios'] = lista_acessorios
    card

    # salvando a foto do carro:
    image = anuncio.find('div', {'class':'image-card'}).img
    urlretrieve(image.get('src'), './output/img/' + image.get('src').split('/')[-1])

    cards.append(card)

cards