Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

erros ao buscar dados da coleção

olás

ao exemplo da aula dentro do "for i in range(pages)" a minha coleção esta em

    anuncios = soup.find('div',{'class': 'coll_right_cat'}).findAll('div',{'class': 'box_default_produto'})

que é praticamente no find pegando o site inteiro e no findAll os varios produtos

então na execução de

    anuncios = soup.find('div',{'class': 'coll_right_cat'}).findAll('div',{'class': 'box_default_produto'})

    for anuncio in anuncios:
        card ={}
        card['id'] = anuncio.find('label', {'class':'linecomparar'}).get('for').split('compare_')[-1]

me dá este erro

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-175-69ea4912b56f> in <module>
     21     for anuncio in anuncios:
     22         card ={}
---> 23         card['id'] = anuncio.find('label', {'class':'linecomparar'}).get('for').split('compare_')[-1]
     24         cards.append(card)
     25 

AttributeError: 'NoneType' object has no attribute 'get'

se eu tirar o findAll em diante, o erro passa a ser

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-176-1c5587c048e0> in <module>
     21     for anuncio in anuncios:
     22         card ={}
---> 23         card['id'] = anuncio.find('label', {'class':'linecomparar'}).get('for').split('compare_')[-1]
     24         cards.append(card)
     25 

TypeError: slice indices must be integers or None or have an __index__ method

Então pra testar se estava ok os identificadores, eu rodei os comandos de forma isolada, linha a linha. Assim se eu rodar o comando da minha coleção e depois o comando que vai me dar a informação que eu quero (anuncio virou anuncios pra pegar a coleção)

anuncios.find('label', {'class':'linecomparar'}).get('for').split('compare_')[-1]

me da este erro

--------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-170-30ae23c6a513> in <module>
----> 1 anuncios.find('label', {'class':'linecomparar'}).get('for').split('compare_')[-1]

~/anaconda3/lib/python3.7/site-packages/bs4/element.py in __getattr__(self, key)
   1576     def __getattr__(self, key):
   1577         raise AttributeError(
-> 1578             "ResultSet object has no attribute '%s'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?" % key
   1579         )

AttributeError: ResultSet object has no attribute 'find'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?

agora se eu tirar o findAll do primeiro comando mencionando e rodar novamente este ultimo, funciona blz, como deveria.

to num vai e volta de Google a 1 hora mas não entendi e nem achei a solução, eu quero obter um numero pra colocar no meu dicionario como a id.

e ai?

2 respostas

Olá Luiz,

Acredito que os primeiros erros sejam causados porque o anuncio.find('label', {'class':'linecomparar'}) não está encontrando nada, assim não pode ser executado o .get() sem nada encontrado. Caso tenha apenas um item no for onde o anuncio.find não encontra nada já é o suficiente para causar um erro e parar todo o programa.

E o último erro acontece porque você executou um find após um find_all, e isso não é possível.

Você está no caminho certo, o passo agora é testar o valor de anuncio.find('label', {'class':'linecomparar'}) e para isso você pode fazer assim:

for anuncio in anuncios:
    print(anuncio.find('label', {'class':'linecomparar'}))
    print('---------')

Baseado no resultado desse for acima você vai adaptar o seu for inicial.

Espero ter ajudado, qualquer dúvida é só falar!

solução!

Oi Lucas

Então... para o "não está encontrando nada" por incrível esta sim, mas só se rodar isolado e com find em abas as situações, todavia a tua dúvida me fez olhar todo o resultado do soup e ai notei que ele aparece menos vezes do que a quantidade de produtos, e ai já que eu tava conseguindo pegar a url do produto com sucesso, modifiquei o meu código e agora eu pego a id do produto do final da url hehe, ficou assim dentro do for

anuncio.find('a').get('href').split("/")[+4]

Ainda não sei bem porque não posso usar um find depois do findAll, pq eu quero pegar um pedaço, um card, de algo que já pegou todos os cards, pra ter uma coleção menor só com os itens uteis (só quero os cards), e não pq ter que pegar mais de meio site pra dentro da coleção e dela pegar o que quero

anuncios = soup.find('div', {"id": "container-cards"}).findAll('div', class_="card")

mas enfim, esta duvida e outras existenciais saem do escopo deste tópico e que consegui resolver, grato Lucas