— Héctor Meleiro 2018/02/07 19:40
El objetivo de este proyecto es scrapear el portal de compra-venta de coches coches.net con la idea de hallar precios medios de coches de segunda mano por provincias y por marcas.
Por ahora, el script genera un índice de links de las últimas 91 páginas de la sección de coches de segunda mano y extrae información básica de las fichas de los anuncios (título del anuncio, marca del coche, precio, provincia, tipo de motor, año de fabricación, kilometraje y url del anuncio). Puesto que en los propios anuncios hay más información que en las fichas, el próximo paso de desarrollo podría ser ampliar el código para generar un índice de links de anuncios para enriquecer aún más la base de datos con campos como la potencia del motor o las emisiones CO2. También es necesario avanzar en 1) el formato del texto para que las tildes se escriban bien en el output, y 2) Mejorar el campo de Marca, que por ahora se consigue extrayendo la primera palabra del título y que en realidad se debería hacer extrayendo el valor del campo Marca en el anuncio de coches.net.
Actualización (15/02/2018):
He “traducido” el web scraper a R, he mejorado algunas cosas y he comprobado que no da errores (he conseguido descargar los últimos 180.000 anuncios en tres horas). Se puede encontrar en mi Github.
A continuación comparto el código de python para el scrapeo.
import csv from urllib import request as urllib2 from bs4 import BeautifulSoup import time outputpath = 'coches.csv' with open(outputpath, 'w') as outfile: writer = csv.writer(outfile) writer.writerow(['num','titulo', 'marca', 'precio', 'provincia', 'motor', 'año', 'km']) num = 0 for counter in range(1,80): url = 'https://www.coches.net/segunda-mano/?pg=' + str(counter) + '&st=1' # Get URL response = urllib2.Request(url) pagedata = urllib2.urlopen(response) html = pagedata.read() # Get links soup = BeautifulSoup(html, "html.parser") bloques = soup.select('.mt-Card-body') for bloque in bloques: num = num + 1 titulo = bloque.select('.mt-CardAd-title .mt-CardAd-titleHiglight')[0].get_text() marca = titulo.split(" ")[0] precio = bloque.select('.mt-CardAd-price .mt-CardAd-titleHiglight')[0].get_text().replace(".", "").replace("€", "") prov = bloque.select('.mt-CardAd-attribute')[0].get_text().replace("km", "").replace(".", "") motor = bloque.select('.mt-CardAd-attribute')[1].get_text().replace("km", "").replace(".", "") año = bloque.select('.mt-CardAd-attribute')[2].get_text().replace("km", "").replace(".", "") km = bloque.select('.mt-CardAd-attribute')[3].get_text().replace("km", "").replace(".", "") link = 'https://www.coches.net/' + bloque.select('.mt-CardAd-link')[0].get('href') print (num, marca, precio, prov, motor, año, km, link) writer.writerow([num, titulo, marca, precio, prov, motor, año, km])
A continuación pego el código en R para visualizar las medias por marca y provincia y los gráficos resultantes.
library(readr) coches <- read_csv("C:/scraping-workshop-master/scrapers/coches.csv", locale(encoding = "ASCII")) library(tidyverse) medias.prov <- coches %>% group_by(provincia) %>% summarise(N = n(), media = mean(precio)) medias.marcas <- coches %>% group_by(marca) %>% summarise(N = n(), media = mean(precio)) prov_plot <- ggplot(medias.prov, aes(x = reorder(provincia, media), y = media)) prov_plot + geom_col() + coord_flip() + labs(x = NULL, y = "Precio medio (€)", title = "Precios medios por provincia") marcas_plot <- ggplot(medias.marcas, aes(x = reorder(marca, media), y = media)) marcas_plot + geom_col() + coord_flip() + labs(x = NULL, y = "Precio medio (€)", title = "Precios medios por marcas")
Aquí los gráficos resultantes:
Aquí un gráfico de dispersión interactivo hecho con Flourish Studio que corelaciona el año del coche con el precio.