IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Crawler sous Scrapy


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2015
    Messages : 22
    Par défaut Crawler sous Scrapy
    Bonsoir à tous !

    Tout d'abord je tiens à préciser que c'est la première fois que je m'essaye au développement sous Python (via scrapy) mais je suis néanmoins familiarisé avec les concepts orientés objets, mais bien plus à l'aise en C.

    La description du projet dans sa globalité n'est pas très importante au regard de la simplicité de ma question:

    - je souhaite déclarer deux tableaux, un contenant des chaînes de caractères et un contenant de simples nombres.
    -une boucle va venir, par exemple, parcourir toutes les positions de mon tableau contenant mes nombres pour venir me les remplacer dans ce code ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import scrapy
    
    
    
    tab1=[1,2,3]
    tab2=['hello','world']
    
    class QuotesSpider(scrapy.Spider):
        name = "histo"
    
        def start_requests(self):
             for i in tab1:
            urls = [
                'https://min-api.cryptocompare.com/data/histohour?fsym=ETH&tsym=BTC&limit=60&aggregate=1&toTs=1452680400&extraParams=your_app_name'
               
            ]
            for url in urls:
                yield scrapy.Request(url=url, callback=self.parse)
    
        def parse(self, response):
            page = response.url.split("/")[-2]
            filename = 'histo-%s.html' % page
            with open(filename, 'wb') as f:
                f.write(response.body)
            self.log('Saved file %s' % filename)
    La partie importante qui me pose problème ici est soulignée en gras, je souhaite que "60" soit remplacé par les différentes valeurs présentes dans mon tab1, en langage C j'aurai écris quelque chose comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for i=0 to 3
     {
    
            urls = [
                'https://min-api.cryptocompare.com/data/histohour?fsym=ETH&tsym=BTC&limit='%d'&aggregate=1&toTs=1452680400&extraParams=your_app_name',tab1[i]
    Malheureusement en cherchant sur des forums je ne trouve rien, bien qu'étant conscient que je ne trouve pas ma réponse parce que la formulation de ma question est que bien trop imprécise.

    J'espère avoir été assez clair, en vous remerciant par avance et en m'excusant des éventuels affronts que j'aurai pu écrire =)

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    C'est plus ou moins similaire en Python
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    >>> indices = [1, 2, 3]
    >>> for i in indices:
    ...     print('indice=%s' % i)
    ... 
    indice=1
    indice=2
    indice=3
    le '%s' peut différer selon le formatage désiré, voir ici:
    https://docs.python.org/3/library/st...ing-formatting


    Edit: je pense que ta fonction génératrice devrait plutôt être ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        def start_requests(self, tab1):
             for i in tab1:
                 urls = 'https://min-api.cryptocompare.com/data/histohour?fsym=ETH&tsym=BTC&limit=%d&aggregate=1&toTs=1452680400&extraParams=your_app_name' % i
                 yield scrapy.Request(url=url, callback=self.parse)
    Note l'argument 'tab1' indispensable parce que inconnu dans l'espace de nom de la fonction.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2015
    Messages : 22
    Par défaut
    Bonjour VinsS et merci pour la rapidité de ta réponse !!!

    Enfait j'avais déjà plus ou moins testé de mettre en argument mon tab1 dans la fonction start_requets, mais visiblement en cherchant un peu, j'ai cru comprendre que pour l'instruction start_request il ne pouvait que posséder exclusivement l'argument self et de fait me voilà bien embêté !!

    Voila mon code adapté avec ton explication :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    import scrapy
     
     
    class QuotesSpider(scrapy.Spider):
        name = "histo"
        tab1=[1000,10]
     
        def start_requests(self, tab1):
            for i in tab1:
                urls = 'https://min-api.cryptocompare.com/data/histohour?fsym=ETH&tsym=BTC&limit=%d&aggregate=1&toTs=1452680400&extraParams=your_app_name' % i
                yield scrapy.Request(url=url, callback=self.parse)
     
     
            def parse(self, response):
                page = response.url.split("/")[-2]
                filename = 'histo-%s.html' % page
                with open(filename, 'wb') as f:
                    f.write(response.body)
                self.log('Saved file %s' % filename)
    L'erreur affichée est de type start_requests() takes exactly 2 arguments (1 given), j'ai également essayé pour résoudre ce problème de déclarer mon tab1 ailleurs dans la fonction mais rien n'y fait

    Si tu as une idée pour contourner le problème je suis preneur =)

  4. #4
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Si tab1 est attribut de classe alors tu peux le supprimer des arguments et utiliser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            for i in self.tab1:
    Est-ce normal que la fonction parse() soit plus indentée que la précédente ?

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2015
    Messages : 22
    Par défaut
    On touche du doigt l'objectif final!!

    Concernant ta question sur l'indentation, ma fonction parse l'est en effet plus que la précédente, mais ce n'est absolument pas une volonté de ma part, c'est vrai qu'en revanche l'indentation semble vraiment importante et problématique sous python, chose que je n'avais jamais expérimenté avant ! est-ce un problème selon toi dans notre cas précis ?

    Maintenant j'ai fait apparaître un autre problème: avec cette boucle, je souhaite mettre dans "urls" les deux urls que ma boucle for va venir créer (une url dans laquelle à correctement été placé le chiffre 1000 et la deuxieme dans laquelle à correctement été placé le chiffre 10)

    Ainsi, je souhaite qu'il m'écrive dans DEUX fichiers différents les informations recueillies sur les deux url différentes (celles crées par ma boucle for) comme s'en suit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    import scrapy
     
     
    class QuotesSpider(scrapy.Spider):
        name = "histo"
        tab1 = [1000,10]
     
        def start_requests(self):
            for i in self.tab1:
                urls = 'https://min-api.cryptocompare.com/data/histohour?fsym=ETH&tsym=BTC&limit=%s&aggregate=1&toTs=1452680400&extraParams=your_app_name' % i
     
            for url in urls:
                yield scrapy.Request(url=url, callback=self.parse)
     
        def parse(self, response):
            page = response.url.split("/")[-2]
            filename = 'histo-%s.html' % page
            with open(filename, 'wb') as f:
                f.write(response.body)
            self.log('Saved file %s' % filename)
    Cependant rien de spécial ne se passe avec ce code, les page html ne se crée pas. Le seul moyen d'avoir un résultat (création d'une page html avec le contenu d'une des deux url) est de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    yield scrapy.Request(url=url, callback=self.parse)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    yield scrapy.Request(url=urls, callback=self.parse)
    et là encore je ne vais avoir que la création de la page html dont les informations viennent de la deuxième url, j'ai comme l'impression qu'au moment de l'écriture, la page html correspondant à ma première url à bien été crée mais écrasée par la création de la deuxième.

    J'ai essayé de conditionner l'écriture par une boucle, mais je pense être sur la mauvaise voie (?)

  6. #6
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Comme indiqué dans mon post #2, ta fonction génératrice devrait être comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        def start_requests(self):
            for i in self.tab1:
                url = 'https://min-api.cryptocompare.com/data/histohour?fsym=ETH&tsym=BTC&limit=%s&aggregate=1&toTs=1452680400&extraParams=your_app_name' % i
                yield scrapy.Request(url=url, callback=self.parse)
    ce que tu fais est une itération sur la chaîne elle-même (la dernière créée)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    >>> for i in [1, 2]:
    ...     idx = "indice=%s" % i
    ... 
    >>> for i in idx:
    ...     print(i)
    ... 
    i
    n
    d
    i
    c
    e
    =
    2
    >>>

Discussions similaires

  1. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  2. webcam : lire sur un port usb en c/c++ ou java. sous win. ?
    Par flo007 dans le forum Choisir un environnement de développement
    Réponses: 2
    Dernier message: 24/05/2002, 23h24
  3. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45
  4. Je ne peux établir une connexion cliente sous Linux.
    Par Anonymous dans le forum CORBA
    Réponses: 5
    Dernier message: 16/04/2002, 15h57
  5. Réponses: 4
    Dernier message: 27/03/2002, 11h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo