Attention chérie,
ça va scraper

Point de départ

“Je veux utiliser dans mon site des données qui proviennent d'autres sites, comment je fais ?”

Méthode 1 “the dream” : les APIs

Problème j'ai besoin d'images de trucs mignons

Solution l'API imgur

→ 

Méthode 2 “tu te démerdes” : le web scraping

En GROS :

3 façons de faire
légèrement différentes
en 3 exemples

Exemple UN

1.

Contexte

Données nécessaires

1.

Étapes (en tant qu'internaute)

  1. Trouver une liste d'extensions structurée sur le net → gandi.net/domain/price/info

1.

Étapes (en tant qu'internaute)

  1. Trouver une liste d'extensions +/- structurée sur le net → gandi.net/domain/price/info
  2. Sélectionner les éléments voulus via le DOM #gandi-price-list th a span

1. Dans notre application

Étapes (dans notre appli PHP, avec simplehtmldom)

  1. Trouver une liste d'extensions structurée sur le net
    
    							$html = file_get_html('https://www.gandi.net/domain/price/info');
    						
  2. Sélectionner les éléments voulus via le DOM
    
    							$elements = $html->find('#gandi-price-list th a span');
    						
  3. Faire ce qu'on veut avec !
    
    							foreach ($elements as $element) {
    							    echo substr($element->plaintext."<br>", 1);
    							}
    						

1. Dans notre application

Résultat

Résultat de la dernière slide

application finale

design réalisé par un développeur

1. Dans notre application : ✔

Exemple DEUZ

2.

Contexte

Données externes nécessaires

Contrainte

2.

On trouve des données structurées sur un site tiers...

zagaz.com/evolution-prix.php
table[summary="prix des carburants en direct"] p

2.

... et on les récupère dans notre site.


				$.get(
				    'http://www.zagaz.com/evolution-prix.php',
				    function(data) {
				        console.log(data);
				    }
				);
			

Ah ouais mais nan...

XMLHttpRequest cannot load http://www.zagaz.com/evolution-prix.php. Origin ... is not allowed by Access-Control-Allow-Origin. 

Comment contourner ça sans proxy sur notre serveur ?

2. Via un service tiers

YQL à la rescousse !

2. Via un service tiers

YQL

2. Via un service tiers

Notre requête YQL


				select p from html
				where url = "http://www.zagaz.com/evolution-prix.php" and (
				    xpath = '//table[@summary="prix des carburants en direct"]/tr/th' or
				    xpath = '//table[@summary="prix des carburants en direct"]/tr/td'
				)
			

...En JS


				$.get("http://query.yahooapis.com/v1/public/yql?format=json&q=...",
				    function(data, status) {
				        if (status === "success") {
				            //nos données sont dans data.query.results
				        }
				    }
				);
			

2. Via un service tiers

Résultat

design aussi réalisé par un développeur

2. Via un service tiers : ✔

DERNIER EXEMPLE§§

3.

Contexte

Données nécessaires

3.

hearthhead.com

3.

hearthhead.com sans JS

3.

Contexte

Données nécessaires

Contrainte

3. Avec un navigateur sans tête

PhantomJS + CasperJS

PhantomJS

CasperJS

PhantomJS est un navigateur :
il comprend le JS !

3. Avec un navigateur sans tête


				var allCards = [];
				casper.start("http://hearthhead.com/cards?filter=type=4:5:7#gallery:0");
				casper.then(function afterStart() {
				    addCurrentPageCards();
				    addPagesCards( this.evaluate(function getNumberOfPages(counterSelector) {
				        var cardsNumber = document.querySelector(counterSelector) ? document.querySelector(counterSelector).innerHTML*1 : null;
				        return cardsNumber !== null ? Math.floor(cardsNumber/40) : 0;
				    }, '.listview-nav > span > b:last-child') );
				});

				//allCards est plein !
				casper.then(function afterCards() {
				    saveJSON("cards.json");
				    saveCSV("images.csv");
				});
				casper.run();
			

3. Avec un navigateur sans tête


				function addCurrentPageCards() {
				    var newCards = casper.evaluate(function getCurrentCards(cardSelector) {
				        var cards = document.querySelectorAll(cardSelector);
				        return Array.prototype.map.call(cards, function(element) {
				            return {
				                name: (element.querySelector('.screenshot-caption span span') ? element.querySelector('.screenshot-caption span span').innerHTML : null),
				                image: (element.querySelector('img') ? element.querySelector('img').src : null)
				            };
				        });
				    }, '.listview-mode-tiled td[align=center]');
				    allCards = allCards.concat(newCards);
				}

				function addPagesCards(numberOfPages) {
				    var currentNav = casper.evaluate(function(selector) {
				        return document.querySelector(selector) ? document.querySelector(selector).innerHTML : null;
				    }, '.listview-nav');
				    _(numberOfPages).times(function() {
				        casper.thenClick('.listview-nav > span + a');
				        casper.then(function afterNewList() {
				            addCurrentPageCards();
				        });
				    });
				}
			

3. Avec un navigateur sans tête

Résultat

3. Avec un navigateur sans tête : ✔

Récapitulatif

Récapitulatif

Fin !

/

par Emmanuel @Leimina - Human Talks Angers 11/2013

http://manu.habite.la/scrap

#