2017-04-15 1 views
0

Questionrvest question de déchirage contenu web/site web commercial de voiture

Je voulais rvest parties spécifiques des sites (la plate-forme de vente de voiture).

Le CSS est franchement trop confus pour moi de comprendre ce qui ne va pas moi-même.

#### scraping the website www.otomoto.pl with used cars ##### 

baseURL_otomoto = "https://www.otomoto.pl/osobowe/?page=" 

i <- 1 

for (i in 1:7000) 
{ 
    link = paste0(baseURL_otomoto,i) 
    out = read_html(link) 
    print(i) 
    print(link) 

    ### building year 
    build_year = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[1]') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

    mileage = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[2]') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

    volume = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[3]') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

    fuel_type = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[4]') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 


    price = html_nodes(out, xpath = '//div[@class="offer-item__price"]') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

    link = html_nodes(out, xpath = '//div[@class="offer-item__title"]') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

    offer_details = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

Les suppositions ce qui pourrait être la raison de ce comportement?

PS # 1.

Comment récupérer toutes les données build_type, kilométrage et fuel_type des offres disponibles sur le site Web analysé en même temps que data.frame? l'utilisation de classes (xpath = '// div [@class = ...) ne fonctionnait pas dans mon cas

PS # 2.

Je voulais rvest les détails des offres réelles à l'aide f.i.

gear_type = html_nodes(out, xpath = '//*[@id="parameters"]/ul[1]/li[10]/div') %>% 
    html_text() %>% 
    str_replace_all("\n","") %>% 
    str_replace_all("\r","") %>% 
    str_trim() 

les arguments

  • dans ul [a] sont dans une (1: 2) &
  • dans li [b] sont pour b dans (01:12)

Malheureusement, ce concept échoue car la trame de données résultante est vide. Tout devine pourquoi?

Répondre

0

Tout d'abord, apprendre sur les sélecteurs CSS et XPath. Vos sélecteurs sont très longs et extrêmement fragiles (certains d'entre eux ne fonctionnaient pas du tout pour moi, seulement deux semaines plus tard). Par exemple, au lieu de:

html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[1]') %>% 
    html_text() 

vous pouvez écrire:

html_nodes(out, css="[data-code=year]") %>% html_text() 

En second lieu, lire la documentation des bibliothèques que vous utilisez. motif str_replace_all peut être une expression régulière, ce qui vous évite un appel (utilisation str_replace_all("[\n\r]", "") au lieu de str_replace_all("\n","") %>% str_replace_all("\r","")). html_text peut faire le découpage de texte pour vous, ce qui signifie que str_trim() n'est pas nécessaire du tout.

Troisièmement, si vous copiez-collez du code, reculez et pense que si la fonction ne serait pas une meilleure solution; Habituellement, il le ferait. Dans votre cas, personnellement, je passerais probablement les appels str_replace_all jusqu'à l'étape de nettoyage des données, quand je les appellerais sur data.frame, en conservant des données entières mises au rebut.


Pour créer data.frame de vos données, appelez la fonction data.frame() avec les noms de colonnes et de contenu, comme ça:

data.frame(build_year = build_year, 
    mileage = mileage, 
    volume = volume, 
    fuel_type = fuel_type, 
    price = price, 
    link = link, 
    offer_details = offer_details) 

ou vous pouvez initialiser les données.cadre avec une seule colonne, puis ajouter d'autres vecteurs comme colonnes:

output_df <- data.frame(build_year = html_nodes(out, css="[data-code=year]") %>% html_text(TRUE)) 
output_df$volume <- html_nodes(out, css="[data-code=engine_capacity]") %>% 
    html_text(TRUE) 

Enfin, il faut noter que data.frame colonnes doivent tous être de la même longueur, alors que certaines des données que vous la ferraille est facultative. Au moment d'écrire cette réponse, j'avais peu d'offres sans capacité de moteur et sans description d'offre. Vous devez utiliser successivement deux appels html_nodes (car un seul sélecteur CSS ne correspondra pas à ce qui n'existe pas). Mais même alors, html_nodes va silencieusement supprimer les données manquantes. Cela peut être contourné par la tuyauterie html_nodes sortie html_node appel:

current_df$volume = out %>% html_nodes("ul.offer-item__params") %>% 
    html_node("[data-code=engine_capacity]") %>% 
    html_text(TRUE) 

La version finale de mon approche de la boucle est inférieure internals. Assurez-vous juste d'initialiser data.frame vide avant de l'appeler et que vous fusionnez la sortie de l'itération en cours avec la trame de données finale (en utilisant par exemple rbind), ou chaque itération écrasera les résultats du précédent. Ou vous pouvez utiliser do.call(rbind, lapply()), qui est idiomatique R pour une telle tâche. En guise de remarque, lorsque vous raclez une grande quantité de données qui changent rapidement, envisagez de découpler le téléchargement des données et le traitement des données. Imaginez qu'il y a un cas d'angle que vous n'avez pas pris en compte et qui provoquera la fin de R. Comment allez-vous procéder si une telle condition apparaît au milieu de vos itérations? Plus longtemps vous restez sur une page, plus vous introduisez de doublons (plus d'offres apparaissent et les offres existantes sont déplacées sur d'autres pages), et plus vous manquez d'offres (la vente est conclue et les offres disparaissent pour toujours).

current_df <- data.frame(build_year = html_nodes(out, css="[data-code=year]") %>% html_text(TRUE)) 

current_df$mileage = html_nodes(out, css="[data-code=mileage]") %>% 
    html_text(TRUE) 

current_df$volume = out %>% html_nodes("ul.offer-item__params") %>% 
    html_node("[data-code=engine_capacity]") %>% 
    html_text(TRUE) 

current_df$fuel_type = html_nodes(out, css="[data-code=fuel_type]") %>% 
    html_text(TRUE) 

current_df$price = out %>% html_nodes(xpath="//div[@class='offer-price']//span[contains(@class, 'number')]") %>% 
    html_text(TRUE) 

current_df$link = out %>% html_nodes(css = "div.offer-item__title h2 > a") %>% 
    html_text(TRUE) %>% 
    str_replace_all("[\n\r]", "") 

current_df$offer_details = out %>% html_nodes("div.offer-item__title") %>% 
    html_node("h3") %>% 
    html_text(TRUE) 
+0

Merci Mirosław. Vos commentaires et suggestions sont définitivement d'une valeur ajoutée énorme. Revenir avec les résultats finaux dès que possible (faisable). –