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

[WEB-SCRAPING] Selenium+bs4

Olá pessoal, boa tarde. Espero que estejam bem.

Estou fazendo o Scraping de alguns sites de anuncio, e deu tudo certo até eu me deparar com o site da OLX.

Estou buscando as informações de valor, localização, metragem, e o link do anúncio, porém esses dados vem com muito resíduo e não consigo usar alguns métodos para minimizar isso, como por exemplo o getText().

Será que alguém poderia me ajudar com isso? Não sei se isso se deve ao fato de os elementos serem 'a' e 'p'.

Além disso, não estou sabendo a melhor forma de conseguir fazer a captura do link que se encontra dentro do href de um elemento, estou tendo que pegar o elemento inteiro para conseguir e vem muito carácter junto.

Fora do código, fiz o for abaixo para testar, mas ele pega todos os links da página e eles vem fora de ordem, e dessa forma não consigo fazer o append para depois gerar o dataset.

for item in soup.findAll('a',lurker="list_id"):
    print(item.get('href'))

Vou deixar o código inteiro abaixo

from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import time

cards=[]

pages = 5

driver = webdriver.Firefox(executable_path='C:/Users/antonio.celes/Desktop/Selenium/geckodriver.exe')


for i in range(pages):

    site ='https://sp.olx.com.br/sao-paulo-e-regiao/imoveis/terrenos/lotes/compra?o='+str(i+1)+'&ps=8000000&ss=11'

    driver.get(site)

    time.sleep(5)

    soup = BeautifulSoup(driver.page_source, 'html.parser')

    anuncios = soup.find('div', {'class' : 'section_OLXad-list'}).findAll('li', class_="item")


    for anuncio in anuncios:
        card = {}

        card['value'] = anuncio.find('p',{'class':"OLXad-list-price"})
        card['location'] = anuncio.find('p',class_="detail-region")
        card['metragem'] = anuncio.find('p',class_="detail-specific")
        card['link'] = anuncio.find('a',lurker="list_id")

        cards.append(card)

dataset = pd.DataFrame(cards)
dataset.to_csv('./output/data/OLXSãoPaulo.csv',sep=';',index = False, encoding = 'utf-8-sig')
dataset

Muito obrigado !!

2 respostas
solução!

Olá Antonio,

Seu código já está bem legal, acredito que o maior problema é a falta de verificação do que é encontrado em cada item.

Para pegar o texto das tags você pode utilizar a função get_text() do BeautifulSoup que você mencionou, o importante é verificar se foi encontrado algum item com o find antes de chamar o get_text(), testando nesse link que você está acessando eu vi que retorna alguns anúncios vazios entre os anúncios corretos.

Sobre buscar o atributo href você pode acessar com ['href'] após selecionar uma tag a, e como no caso anterior é importante verificar se realmente foi encontrado algo.

Juntando isso tudo, recomendo separar em duas funções essa parte de verificar se algo foi encontrado e então pegar o texto ou link dependendo do caso, só por questões de organização:

# Função para pegar o texto
def get_text(bs_tag):
    if bs_tag:
        return bs_tag.get_text().strip().replace('\n', '').replace('\t', '')
    else:
        return ''

# Função para pegar o href do link
def get_link(bs_tag):
    if bs_tag:
        return bs_tag['href']
    else:
        return ''

Então no for de cada anúncio utilizamos as funções acima:

for anuncio in anuncios:
    card = {}

    card['value'] = get_text(anuncio.find('p', {'class':"OLXad-list-price"}))
    card['location'] = get_text(anuncio.find('p', class_="detail-region"))
    card['metragem'] = get_text(anuncio.find('p', class_="detail-specific"))
    # Mudei a forma de selecionar o link aqui
    card['link'] = get_link(anuncio.find('a', href=True))

    # Salvamos apenas os cards que não estão vazios
    if len(card['value']):
        cards.append(card)

E esse foi o resultado após essas alterações:

Agora se ainda for necessário algum tratamento em alguma coluna, o melhor é fazer a partir do DataFrame criado.

Abaixo segue um link do Colaboratory com o código que eu fiz completo:

https://colab.research.google.com/drive/1zXA7Kfd2n_xUgdpxawBHuw_Y37XxMuer

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

Olha... impressionante!!

Muito obrigado mesmo! Não tenho nem palavras !