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

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

Rodei o código estruturado exatamente como explicado ao longo do curso, no entanto, ao final gerou o seguinte ERROR:

Importando bibliotecas

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

Declarando variável cards

cards = []

Obtendo o HTML

url = 'https://ba.olx.com.br/imoveis?q=village' headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'} req = Request(url, headers = headers) response = urlopen(req) html = response.read().decode('utf-8') soup = BeautifulSoup(html, 'html.parser')

Obtendo as TAGs de interesse

anuncios = soup.find('ul', {"id": "ad-list"}).findAll('li', class_="sc-1fcmfeb-2 ggOGTJ")

Coletando as informações dos CARDS

for anuncio in anuncios: card = {}

# Informações
card['valor'] = anuncio.find('p', {'class': 'fnmrjs-16 jqSHIm'}).get_text()
card['Características'] = anuncio.find('p', {'class': 'jm5s8b-0 jDoirm'}).get_text()
card['Localização'] = anuncio.find('p', {'class': 'fnmrjs-13 hdwqVC'}).get_text()
card['Tipo'] = anuncio.find('p', {'class': 'fnmrjs-14 iIprpQ'}).get_text()
card['Data_anuncio'] = anuncio.find('p', {'class': 'fnmrjs-19 eJIIxH'}).get_text()
card['nome'] = anuncio.find('h2', {'class': 'fnmrjs-10 deEIZJ'}).get_text() 

# Adicionando resultado a lista cards
cards.append(card)

# Imagens
image = soup.find('div', {'class':'fnmrjs-5 jksoiN'}).img
urlretrieve(image.get('src'), 'C:\\Users\\ADM\\WebScraping\\output\\img/' + image.get('src').split('/')[-1])

Criando um DataFrame com os resultados

dataset = pd.DataFrame(cards) dataset.to_csv('C:\Users\ADM\WebScraping\output\data/dataset.csv', sep=';', index = False, encoding = 'utf-8-sig') dataset


AttributeError Traceback (most recent call last) in 23 24 # Informações ---> 25 card['valor'] = anuncio.find('p', {'class': 'fnmrjs-16 jqSHIm'}).get_text() 26 card['Características'] = anuncio.find('p', {'class': 'jm5s8b-0 jDoirm'}).get_text() 27 card['Localização'] = anuncio.find('p', {'class': 'fnmrjs-13 hdwqVC'}).get_text()

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

Como faço para solucionar?

2 respostas
solução!

Olá Willy,

O problema é que nem sempre vai existir a tag p com a classe fnmrjs-16 jqSHIm dentro da lista de anúncios que você selecionou, veja por exemplo o terceiro anúncio (anuncios[2]):

<li class="sc-1fcmfeb-2 ggOGTJ"></li>

Aqui nem mesmo uma tag p temos, assim o código anuncio.find('p', {'class': 'fnmrjs-16 jqSHIm'}) não vai retornar nada e não podemos executar o .get_text() a partir de nada.

Nesse caso o melhor caminho é verificar se existe a tag p com o valor:

for anuncio in anuncios:
    # Caso seja encontrada a tag com o valor continuamos a execução,
    # caso contrário pulamos para o próximo anúncio
    if anuncio.find('p', {'class': 'fnmrjs-16 jqSHIm'}):
        card = {}

        # Informações
        card['valor'] = anuncio.find('p', {'class': 'fnmrjs-16 jqSHIm'}).get_text()
        card['Características'] = anuncio.find('p', {'class': 'jm5s8b-0 jDoirm'}).get_text()
        card['Localização'] = anuncio.find('p', {'class': 'fnmrjs-13 hdwqVC'}).get_text()
        card['Tipo'] = anuncio.find('p', {'class': 'fnmrjs-14 iIprpQ'}).get_text()
        card['Data_anuncio'] = anuncio.find('p', {'class': 'fnmrjs-19 eJIIxH'}).get_text()
        card['nome'] = anuncio.find('h2', {'class': 'fnmrjs-10 deEIZJ'}).get_text() 

        # Adicionando resultado a lista cards
        cards.append(card)

Essa é uma solução específica para esse cenário, eu estou confiando que caso exista a tag p com a classe fnmrjs-16 jqSHImtodas as outras tags buscadas estarão presentes (Características, Localização, Tipo, ...).

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

Jóia Lucas. Deu certo amigo! Muitíssimo obrigado!