fix LeBonCoin bridge (#747)

This commit is contained in:
Antoine Cadoret 2018-07-16 20:13:08 +02:00 committed by Teromene
parent c7b0c9fd31
commit 87fc9e9156
1 changed files with 163 additions and 131 deletions

View File

@ -1,11 +1,10 @@
<?php <?php
class LeBonCoinBridge extends BridgeAbstract { class LeBonCoinBridge extends BridgeAbstract {
const MAINTAINER = '16mhz'; const MAINTAINER = 'jacknumber';
const NAME = 'LeBonCoin'; const NAME = 'LeBonCoin';
const URI = 'https://www.leboncoin.fr/'; const URI = 'https://www.leboncoin.fr/';
const DESCRIPTION = 'Returns most recent results from LeBonCoin for a const DESCRIPTION = 'Returns most recent results from LeBonCoin';
region, and optionally a category and a keyword .';
const PARAMETERS = array( const PARAMETERS = array(
array( array(
@ -14,125 +13,137 @@ region, and optionally a category and a keyword .';
'name' => 'Région', 'name' => 'Région',
'type' => 'list', 'type' => 'list',
'values' => array( 'values' => array(
'Toute la France' => 'ile_de_france/occasions', 'Toute la France' => '',
'Alsace' => 'alsace', 'Alsace' => '1',
'Aquitaine' => 'aquitaine', 'Aquitaine' => '2',
'Auvergne' => 'auvergne', 'Auvergne' => '3',
'Basse Normandie' => 'basse_normandie', 'Basse Normandie' => '4',
'Bourgogne' => 'bourgogne', 'Bourgogne' => '5',
'Bretagne' => 'bretagne', 'Bretagne' => '6',
'Centre' => 'centre', 'Centre' => '7',
'Champagne Ardenne' => 'champagne_ardenne', 'Champagne Ardenne' => '8',
'Corse' => 'corse', 'Corse' => '9',
'Franche Comté' => 'franche_comte', 'Franche Comté' => '10',
'Haute Normandie' => 'haute_normandie', 'Haute Normandie' => '11',
'Ile de France' => 'ile_de_france', 'Ile de France' => '12',
'Languedoc Roussillon' => 'languedoc_roussillon', 'Languedoc Roussillon' => '13',
'Limousin' => 'limousin', 'Limousin' => '14',
'Lorraine' => 'lorraine', 'Lorraine' => '15',
'Midi Pyrénées' => 'midi_pyrenees', 'Midi Pyrénées' => '16',
'Nord Pas De Calais' => 'nord_pas_de_calais', 'Nord Pas De Calais' => '17',
'Pays de la Loire' => 'pays_de_la_loire', 'Pays de la Loire' => '18',
'Picardie' => 'picardie', 'Picardie' => '19',
'Poitou Charentes' => 'poitou_charentes', 'Poitou Charentes' => '20',
'Provence Alpes Côte d\'Azur' => 'provence_alpes_cote_d_azur', 'Provence Alpes Côte d\'Azur' => '21',
'Rhône-Alpes' => 'rhone_alpes', 'Rhône-Alpes' => '22',
'Guadeloupe' => 'guadeloupe', 'Guadeloupe' => '23',
'Martinique' => 'martinique', 'Martinique' => '24',
'Guyane' => 'guyane', 'Guyane' => '25',
'Réunion' => 'reunion' 'Réunion' => '26'
) )
), ),
'c' => array( 'c' => array(
'name' => 'Catégorie', 'name' => 'Catégorie',
'type' => 'list', 'type' => 'list',
'values' => array( 'values' => array(
'TOUS' => '', 'Toutes catégories' => '',
'EMPLOI' => '_emploi_', 'EMPLOI' => array(
'Emploi et recrutement' => '71',
'Offres d\'emploi et jobs' => '33'
),
'VEHICULES' => array( 'VEHICULES' => array(
'Tous' => '_vehicules_', 'Tous' => '1',
'Voitures' => 'voitures', 'Voitures' => '2',
'Motos' => 'motos', 'Motos' => '3',
'Caravaning' => 'caravaning', 'Caravaning' => '4',
'Utilitaires' => 'utilitaires', 'Utilitaires' => '5',
'Équipement Auto' => 'equipement_auto', 'Equipement Auto' => '6',
'Équipement Moto' => 'equipement_moto', 'Equipement Moto' => '44',
'Équipement Caravaning' => 'equipement_caravaning', 'Equipement Caravaning' => '50',
'Nautisme' => 'nautisme', 'Nautisme' => '7',
'Équipement Nautisme' => 'equipement_nautisme' 'Equipement Nautisme' => '51'
), ),
'IMMOBILIER' => array( 'IMMOBILIER' => array(
'Tous' => '_immobilier_', 'Tous' => '8',
'Ventes immobilières' => 'ventes_immobilieres', 'Ventes immobilières' => '9',
'Locations' => 'locations', 'Locations' => '10',
'Colocations' => 'colocations', 'Colocations' => '11',
'Bureaux & Commerces' => 'bureaux_commerces' 'Bureaux & Commerces' => '13'
), ),
'VACANCES' => array( 'VACANCES' => array(
'Tous' => '_vacances_', 'Tous' => '66',
'Location gîtes' => 'locations_gites', 'Locations & Gîtes' => '12',
'Chambres d\'hôtes' => 'chambres_d_hotes', 'Chambres d\'hôtes' => '67',
'Campings' => 'campings', 'Campings' => '68',
'Hôtels' => 'hotels', 'Hôtels' => '69',
'Hébergements insolites' => 'hebergements_insolites' 'Hébergements insolites' => '70'
), ),
'MULTIMEDIA' => array( 'MULTIMEDIA' => array(
'Tous' => '_multimedia_', 'Tous' => '14',
'Informatique' => 'informatique', 'Informatique' => '15',
'Consoles & Jeux vidéo' => 'consoles_jeux_video', 'Consoles & Jeux vidéo' => '43',
'Image & Son' => 'image_son', 'Image & Son' => '16',
'Téléphonie' => 'telephonie' 'Téléphonie' => '17'
), ),
'LOISIRS' => array( 'LOISIRS' => array(
'Tous' => '_loisirs_', 'Tous' => '24',
'DVD / Films' => 'dvd_films', 'DVD / Films' => '25',
'CD / Musique' => 'cd_musique', 'CD / Musique' => '26',
'Livres' => 'livres', 'Livres' => '27',
'Animaux' => 'animaux', 'Animaux' => '28',
'Vélos' => 'velos', 'Vélos' => '55',
'Sports & Hobbies' => 'sports_hobbies', 'Sports & Hobbies' => '29',
'Instruments de musique' => 'instruments_de_musique', 'Instruments de musique' => '30',
'Collection' => 'collection', 'Collection' => '40',
'Jeux & Jouets' => 'jeux_jouets', 'Jeux & Jouets' => '41',
'Vins & Gastronomie' => 'vins_gastronomie' 'Vins & Gastronomie' => '48'
), ),
'MATÉRIEL PROFESSIONNEL' => array( 'MATERIEL PROFESSIONNEL' => array(
'Tous' => '_materiel_professionnel_', 'Tous' => '56',
'Matériel Agricole' => 'mateiel_agricole', 'Matériel Agricole' => '57',
'Transport - Manutention' => 'transport_manutention', 'Transport - Manutention' => '58',
'BTP - Chantier - Gros-œuvre' => 'btp_chantier_gros_oeuvre', 'BTP - Chantier Gros-oeuvre' => '59',
'Outillage - Matériaux 2nd-œuvre' => 'outillage_materiaux_2nd_oeuvre', 'Outillage - Matériaux 2nd-oeuvre' => '60',
'Équipements Industriels' => 'equipement_industriels', 'Équipements Industriels' => '32',
'Restauration - Hôtellerie' => 'restauration_hotellerie', 'Restauration - Hôtellerie' => '61',
'Fournitures de Bureau' => 'fournitures_de_bureau', 'Fournitures de Bureau' => '62',
'Commerces & Marchés' => 'commerces_marches', 'Commerces & Marchés' => '63',
'Matériel médical' => 'materiel_medical' 'Matériel Médical' => '64'
), ),
'SERVICES' => array( 'SERVICES' => array(
'Tous' => '_services_', 'Tous' => '31',
'Prestations de services' => 'prestations_de_services', 'Prestations de services' => '34',
'Billetterie' => 'billetterie', 'Billetterie' => '35',
'Évènements' => 'evenements', 'Evénements' => '49',
'Cours particuliers' => 'cours_particuliers', 'Cours particuliers' => '36',
'Covoiturage' => 'covoiturage' 'Covoiturage' => '65'
), ),
'MAISON' => array( 'MAISON' => array(
'Tous' => '_maison_', 'Tous' => '18',
'Ameublement' => 'ameublement', 'Ameublement' => '19',
'Électroménager' => 'electromenager', 'Electroménager' => '20',
'Arts de la table' => 'arts_de_la_table', 'Arts de la table' => '45',
'Décoration' => 'decoration', 'Décoration' => '39',
'Linge de maison' => 'linge_de_maison', 'Linge de maison' => '46',
'Bricolage' => 'bricolage', 'Bricolage' => '21',
'Jardinage' => 'jardinage', 'Jardinage' => '52',
'Vêtements' => 'vetements', 'Vêtements' => '22',
'Chaussures' => 'chaussures', 'Chaussures' => '53',
'Accessoires & Bagagerie' => 'accessoires_bagagerie', 'Accessoires & Bagagerie' => '47',
'Montres & Bijoux' => 'montres_bijoux', 'Montres & Bijoux' => '42',
'Équipement bébé' => 'equipement_bebe', 'Equipement bébé' => '23',
'Vêtements bébé' => 'vetements_bebe' 'Vêtements bébé' => '54',
), ),
'AUTRES' => 'autres' 'AUTRES' => '37'
)
),
'o' => array(
'name' => 'Vendeur',
'type' => 'list',
'values' => array(
'Tous' => '',
'Particuliers' => 'private',
'Professionnels' => 'pro',
) )
) )
) )
@ -140,50 +151,71 @@ region, and optionally a category and a keyword .';
public function collectData(){ public function collectData(){
$category = $this->getInput('c'); $params = array(
if(empty($category)) { 'text' => $this->getInput('k'),
$category = 'annonces'; 'region' => $this->getInput('r'),
'category' => $this->getInput('c'),
'owner_type' => $this->getInput('o'),
);
$url = self::URI . 'recherche/?' . http_build_query($params);
$html = file_get_contents($url)
or returnServerError('Could not request LeBonCoin. Tried: ' . $url);
if(!preg_match('/^<script>window.FLUX_STATE[^\r\n]*/m', $html, $matches)) {
returnServerError('Could not parse JSON in page content.');
} }
$html = getSimpleHTMLDOM(self::URI $clean_match = str_replace(
. $category array('</script>', '<script>window.FLUX_STATE = '),
. '/offres/' array('', ''),
. $this->getInput('r') $matches[0]
. '/?f=a&th=1&q=' );
. urlencode($this->getInput('k'))) $json = json_decode($clean_match);
or returnServerError('Could not request LeBonCoin.');
$list = $html->find('.tabsContent', 0); if($json->adSearch->data->total === 0) {
if($list === null) {
return; return;
} }
$tags = $list->find('li'); foreach($json->adSearch->data->ads as $element) {
foreach($tags as $element) { $item['title'] = $element->subject;
$item['content'] = $element->body;
$item['date'] = $element->index_date;
$item['timestamp'] = strtotime($element->index_date);
$item['uri'] = $element->url;
$item['ad_type'] = $element->ad_type;
$item['author'] = $element->owner->name;
$element = $element->find('a', 0); if(isset($element->location->city)) {
$item = array(); $item['city'] = $element->location->city;
$item['uri'] = $element->href; $item['content'] .= ' -- ' . $element->location->city;
$title = html_entity_decode($element->getAttribute('title'));
$content_image = $element->find('div.item_image', 0)->find('.lazyload', 0);
if($content_image !== null) {
$content = '<img src="' . $content_image->getAttribute('data-imgsrc') . '" alt="thumbnail">';
} else {
$content = '';
} }
$date = $element->find('aside.item_absolute', 0)->find('p.item_sup', 0);
$detailsList = $element->find('section.item_infos', 0); if(isset($element->location->zipcode)) {
$item['zipcode'] = $element->location->zipcode;
}
for($i = 0; $i <= 1; $i++) $content .= $detailsList->find('p.item_supp', $i)->plaintext; if(isset($element->price)) {
$price = $detailsList->find('h3.item_price', 0);
$content .= $price === null ? '' : $price->plaintext; $item['price'] = $element->price[0];
$item['content'] .= ' -- ' . current($element->price) . '€';
}
if(isset($element->images->urls)) {
$item['thumbnail'] = $element->images->thumb_url;
$item['enclosures'] = array();
foreach($element->images->urls as $image) {
$item['enclosures'][] = $image;
}
}
$item['title'] = $title;
$item['content'] = $content . $date;
$this->items[] = $item; $this->items[] = $item;
} }
} }