Category Archives: Linux

Scrapy, l’outil de crawl facile pour extraire des données

Quelque soit la raison, bonne ou mauvaise, pour laquelle vous pourriez être amenés à avoir besoin de crawler des sites pour en extraire des données et bien sachez qu’il existe un outil très pratique pour faire cela: Scrapy. Tous ceux qui ont eu à faire une fois un crawler savent que c’est souvent une expérience douloureuse et fastidieuse. Il faut tenir compte des redirections, gérer les erreurs, gérer l’encoding, etc…L’avantage d’utiliser un outil c’est qu’il englobe tout cela dans un socle et que le développeur n’a plus besoin de gérer ces problèmes, c’est ce que propose Scrapy, un outil écrit en Python et qui utilise XPath. Le coeur de métier de l’outil c’est de crawler une ou plusieurs pages et de s’occuper des toutes les problématiques citées ci-dessus, charge ensuite à l’utilisateur de dire quelles pages il souhaite visiter, quelles pages il souhaite parser, et ce qu’il veut parser dans les pages. Je vous propose un petit tutorial pour l’installation, la configuration et un petit test, car il faut avouer que j’ai eu un peu de mal avec la doc de l’outil :-)  En avant pour le tutorial !

I – Installation

Sous Linux / Debian ajoutez le repository deb http://archive.scrapy.org/ubuntu oneiric main proposé par Scrapy (Documentation) dans votre fichier /etc/apt/sources.list, puis exécutez les commandes suivantes :

apt-get update
apt-get install scrapy-0.15 python-mysqldb

Notez qu’il y a plusieurs versions de Scrapy disponibles, vous prenez celle que vous voulez, là j’ai mis la dernière, la 0.15. J’ai aussi ajouté python-mysqldb pour pouvoir stocker dans un MySQL ce qui est crawlé.

II – Création d’un workspace

Pour commencer votre crawler il faut créer un environnement de travail, sorte de coquille vide, ou presque, dans laquelle on va ensuite travailler, pour se faire :

scrapy startproject mycrawler

Dans le dossier créé, il y a un scrapy.cfg, personnellement je n’y ai pas touché, la configuration va se faire dans le sous-dossier, mycrawler. Dans ce sous-répertoire on trouve :
- __init__.py : je n’y ai pas touché
- items.py : on y mettra les « objets » que l’on va manipuler
- pipelines.py : on y mettra les méthodes post-crawl sur les objets (je stocke où, je dédoublonne, etc…)
- settings.py : on y mettra les paramètres de configuration

Dans le sous-répertoire spiders, on y mettra les scripts de nos crawlers.

III – Préparation

Dans le fichier settings.py vous pouvez déjà ajouter que vous voulez exporter en CSV et le nom du fichier dans lequel sortiront vos données, vous pourrez commenter ces lignes plus tard :

# Store
FEED_URI='mycrawler-results.csv'
FEED_FORMAT='csv

Dans le fichier items.py, on y met les « objets » que l’on aura récupérer en fin de traitement d’une page HTML, par exemple :

from scrapy.item import Item, Field

class MycrawlerItem(Item):
    title = Field()
    url = Field()

IV – Le crawler proprement dit

Dans le dossier spiders, vous devez créer un fichier python pour votre nouveau « spider », par exemple moncrawler.py contenant :

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.selector import HtmlXPathSelector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor

from mycrawler.items import MycrawlerItem

class MyCrawlerSpider(CrawlSpider):
    # nom du crawler à spécifier lors de l'exécution
    name = 'mycrawler'

    # domaine(s) sur le ou lesquels le crawler aura le droit d'aller
    allowed_domains = ['www.liteweb.fr']

    # point de départ : vous pouvez mettre une liste d'url, séparées par des virgules
    start_urls = ['http://www.liteweb.fr']

    # très important : les régles en fonction du schéma des urls (c'est des regexp)
    rules = [
        # on autorise /article et que l'on va parser avec la methode parse_item, et que l'on va aussi suivre pour extraire des liens
        Rule(SgmlLinkExtractor(allow=['\/article\/']), callback='parse_item',follow='True'),

        # on autorise le crawler à parcourir et à extraire des liens de tous les .html, mais pas si y'a /about dans l'url
        Rule(SgmlLinkExtractor(allow=['\.html'],deny=['\/about']), follow='True')
    ]

    def parse_item(self, response):
        hxs = HtmlXPathSelector(response)
        item = MycrawlerItem()
        item['title'] = hxs.select("//h1/text()").extract()
        item['url']= response.url

        # exemples de scrap plus complexes avec des regexp :
        # item['datereview'] = mtabletd.select('./tr[position()=2]/td[position()=3]/strong/text()').re(r'em (.*)$')
        # item['note'] = mtabletd.select('./tr[position()=2]/td/table/tr/td[position()=3]/img/@src').re(r'avloja_m([0-9]+).gif')
        # item['textreview'] = mtabletd.select('./tr[position()=4]/td/div/p/span[@class="opncomp"]/text()').extract()

        return item

Ce fichier est le plus important, c’est ici que tout est à configurer. Notez que pour start_urls vous pouvez mettre une liste d’urls comme points d’entrées pour aller plus vite. Que les Rule sont aussi importantes pour savoir comment le spider va se comporter, il faut mettre des regexps, jouer avec les deny() et allow(). Il est souvent inutile de parser certains formats d’urls, par exemple celles qui on un ordre de tri (order by date, price, etc..) c’est du temps de perdu pour le crawler. Enfin il faudra aussi avoir quelques notions de XPath pour extraire les données de l’HTML.

V – Lancer son crawler

Rien de plus simple, depuis le répertoire racine de notre projet, là où il y a le fichier .cfg :

scrapy crawl mycrawler

Le crawler se lance, il va parcourir tout ce qu’il a le droit de parcourir et parser les pages qu’on lui a demandé, à la fin il écrira les données dans le fichier .csv que l’on a mis dans la configuration.

VI – Stockage dans une base de donnée MySQL

On va ajouter ce qu’il faut dans notre fichier pipelines.py pour stocker chaque item qui est parsé :

class MySQLPipeline(object):
    def __init__(self):
        import MySQLdb
        self.db = MySQLdb.connect(host="SERVER", user="USERNAME", passwd="PASSWORD", db="DATABASE") 

    def process_item(self, item, spider):
        cursor = self.db.cursor()
        sql = "insert into testscrapy(title,url) values ('%s','%s')" % (item['title'][0],item['url'][0]))
        cursor.execute(sql)
        return item

    def spider_closed(self, spider):
        self.db.commit()

A chaque fois qu’un item sera capturé, la méthode process_item sera appelée pour stocker l’objet. A partir de maintenant vous pouvez commenter les lignes dans le fichier de configuration pour arrêter de stocker les résultats dans le fichier CSV et ajouter le pipeline, dans settings.py :

#FEED_URI='mycrawler-results.csv'
#FEED_FORMAT='csv

ITEM_PIPELINES = ['mycrawler.pipelines.MySQLPipeline']

Voilà votre premier crawler avec Scrapy est fini, amusez-vous bien, vous pouvez maintenant écrire un GoogleBot :-)

Problème de modification des menus dans KDE

Si comme moi vous avez un soucis avec les modifications des menus dans KDE, et notamment l’ajout de nouvelles entrées qui ne s’affichent pas, voilà une solution qui fonctionne :
Lorsque vous créez une nouvelle entrée, prenez soin de cocher la case « Afficher uniquement dans KDE« , sans cela la nouvelle entrée ne s’affichera pas. Les liens sont pourtant bien créés dans la liste des menus (~/.config/menus/applications-kmenuedit.menu) mais les fichiers de description (~/.local/share/applications/*.desktop) contiennent une ligne vide pour l’entrée OnlyShowIn alors qu’il devrait y avoir OnlyShowIn=KDE;, ce qui n’affiche pas la nouvelle entrée :-(

[ Plus d'infos http://bugs.kde.org/283658 ]

Bref, j’ai installé openSUSE 12.1

Soyons clairs dès le début : si j’ai installé openSUSE 12.1 c’est pour deux raisons : Premièrement parce que je recherche une distribution récente disposant de l’interface KDE par défaut, et deuxièment parce que LinuxMint me fait attendre (pour ne pas dire poireauter) depuis trop longtemps la version KDE justement ! Du coup j’y ai vu l’opportunité de revenir vers la distribution que j’avais utilisé un paquet d’années aux alentours de la version 6.quelquechose… A l’époque elle disposait déjà de KDE, et de YaST, en mode console, puis en mode graphique, donc je me suis légitimement dit que 10 ans plus tard elle devait tout déchirer cette distribution ! J’ai donc téléchargé et gravé le DVD de 4.2Go et je me suis lancé tout content… et là c’est le drame !

L’installation : Première remarque, avec une version DVD de 4Go y’a pas de version Live pour tester avant de se dire « ok, j’installe, elle déchire tout comme prévu »… Du coup je me suis lancé, j’en suis pas à ma première install donc je ne « risquais » pas grand chose, logiquement je devrais m’en sortir. Mais qu’en est-il d’un débutant ? Prendra-t-il le risque de l’installer ? Non je ne pense pas. Continuons. Deuxièmement : l’installation est propre mais pas très fluide, on a vu mieux, on est en 2011, je m’attendais à mieux ! Troisièmement : L’installation est longue, j’ai peur que l’on m’installe tout le DVD à ce rythme, et plein de trucs dont je n’aurais jamais besoin…

Le bureau : L’installation est finie, je découvre le bureau. C’est propre, et y’a jusque ce qu’il faut sur le bureau pour ne pas polluer dès le début et perdre l’utilisateur. C’est sobre, hormis le fond d’écran un peu trop flashy à mon gout, et les fontes un peu petites, c’est Green, mais ça ira, première impression : ça va.

Menu / Applications : C’est bien ce que je craignais, le menu des applications embarque un peu trop de choses. Il est mal conçu (3 niveaux) c’est pas « user-friendly » du tout, mal traduit (Drawing Program), y’a plusieurs fois les mêmes choses (Lecteur de flux), c’est un peu la faute de KDE, mais quand même, l’impression n’est pas franchement bonne, même si je sais que je peux tout changer. Quand on a fini l’installation d’un OS, pour moi, on a des besoins très simples au début : un navigateur, un lecteur DVD/Divx, un lecteur MP3 simple (et pas le même que le Divx si possible), un client mail, une suite Office, un gros bouton « Configurer mon Wifi » sur le bureau et un autre « Installer des logiciels ». L’équipe de Linux Mint a refait un menu, beaucoup plus simple, et ça marche beaucoup mieux.

Les applications : Bon là, ça m’a vite fatigué, en vrac : Dolphin m’a planté au visage quand je veux afficher la barre de menu, y’a que le raccourci qui marche. Les codecs pour lire du Divx ou du MP3 ne sont pas installés (je sais les histoires de droits etc..) mais pour les ajouter c’est la croix et la bannière, et franchement Madame Michue n’y arrivera pas. Même après l’installation des codecs VLC ne marche pas (mpgv/a non supporté), Kmplayer non plus, finalement y’a que Kaffeine qui accepte de lire mon film de vacance… Le parcourt du réseau avec Dolphin ne marche pas non plus, on en est toujours au même point qu’il y a 10 ans pour la gestion des partages réseaux, dommage.

Système : J’ai trouvé le système assez lent dans l’ensemble, et la gestion réseau très lente aussi, la navigation internet se bloque sans cesse. YaST n’est pas non plus un exemple de fluidité, plein de fenêtres s’ouvrent et se ferment pour afficher toutes les actions qui sont faites, ça fera peur à l’utilisateur je pense ! Et enfin, dernier point, Grub qui affiche des entrées complétement pourries, c’est misérable… et je retrouve avec 2 entrées pour le Windows (et oui, ordinateur professionnel oblige) nommées « windows 1″, windows 2″, parce qu’il y a une recovery Dell dessus. et avant, des entrées aux noms illisibles « Linux openSUSE 12.1 blabla blablabla 3 kilomètre d’informations pour le nom on s’en fout… » :-( Faites simple les gars !

Tout cela pour dire qu’il y a du potentiel avec une distribution comme celle là, mais que les 10% qui restent pour faire que la distribution soit parfaite ne sont jamais fait. Linux Mint, et Ubuntu avant, font ce travail, et c’est pour ça qu’elles fonctionnent auprès du grand public, l’utilisateur n’est pas pollué par des choses qu’il n’a pas à voir ou à changer. Je vais garder openSUSE encore un peu mais je doute qu’elle reste très longtemps si j’ai encore trop de mauvaises expériences.

Bref, j’ai installé openSUSE 12.1

Serveur formaté, passage en LinuxMint 11 et WordPress

Voilà tout est dans le titre ! A l’occasion du formatage de printemps du serveur je me suis rabattu sur une version Gnome moins gourmande en ressources car ça n’était plus possible avec KDE. Après quelques  tests d’Ubuntu et de sa nouvelle interface Unity je me suis finalement tourné vers la dernière version de LinuxMint 11 et le constat est sans appel : elle est parfaite, finition impeccable, tout est nickel ! J’en ai  profité pour passer ce blog à WordPress, ce qui m’évite aussi d’avoir un Tomcat qui tourne pour 3 jsp et me fait économiser encore quelques ressources ! Reste à rapatrier les albums photo mais ca ne devrait pas être trop compliqué avec le plugin Gallery.

Désactiver les effets graphiques sous KDE 4 pour accélérer votre Linux


Il y’a une particularité de Linux qui n’est plus vraiment vraie maintenant c’est sa « légèreté ». En effet jusqu’à  il n’y a pas si longtemps on pouvait conseiller à  quelqu’un de passer à  Linux pour donner une deuxième jeunesse à  une vieille machine (une Machine à  Expresso ?!? :-p) parce que l’environnement graphique était plus léger par exemple. Il faut bien l’admettre avec Compiz, KDE4, Metisse, Beryl et autres effets graphiques les plus délirants les uns que les autres, la fluidité en a pris un sacré coup au passage :-(

Je l’ai personnellement constaté quand je suis passé à la dernière version de Linux Mint et que mon KDE 4 ramait à mort à cause des effets… Donc je me suis mis à la recherche d’une solution, et je l’ai trouvé ! Ils sont bien les développeurs Linux, ils pensent à tout ;-)

Donc si vous êtes comme moi avec pleins d’effets dans KDE 4 et que vous voulez tout couper, c’est hyper simple, perso j’ai pas trouvé de case à cocher donc je donne la version « fichier de config »:

Dans Dolphin il faut aller dans votre répertoire utilisateur /home/user/.kde4/share/config/ et ouvrir le fichier kwinrc avec kate (ou kwrite). Notez que vous pouvez utiliser la barre d’url modifiable pour le faire ou afficher les fichiers cachés pour naviguer.

Dans le fichier, si aucune section [Compositing] n’existe, ajoutez en une et ajoutez dessous une ligne: Enabled=false ce qui donne au final:


[Compositing]
Enabled=false

Pour les puristes, rien de nous empêche de vous le faire à  la ligne de commande:

kwriteconfig --file kwinrc --group Compositing --key Enabled false

Et enfin, pour l’activer/désactiver à la volée, il existe aussi un raccourci : Shift + Alt + F12

Enjoy !