Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Problème avec requests pour un scraper

+3 votes

Je tente de développer un scraper pour extraire les données sur les projets du site FaireMTL: https://fairemtl.ca/fr/projets

J'avais fais la liste des 70 liens des projets que j'utilise à partir du fichier fairemtl.csv.

Ex.: https://fairemtl.ca/fr/affichage-dynamique-vers-stationnement-disponible

Mais pour certains liens, le requests.get ne retourne rien.

Ex.: https://fairemtl.ca/fr/24h-linnovation-volet-ville-intelligente

Exécution du code

J'ai essayé en mettant u délai, ne marche pas plus.

C'est toujours les mêmes liens qui ne fonctionnent pas.

Fichiers ici

#Code développé en Python 3.4

import unicodecsv
import csv
import time
import requests
import re
from bs4 import (
    BeautifulSoup,
    BeautifulStoneSoup,
)

#Compteur pour identifier les projets
compteur = 0;

#Ouverture du fichier pour sauvegarder les données du scraping
output = open('donnees.csv', "w")
fdonnees = unicodecsv.writer(output, delimiter = ';')

#Inscrire le nom des champs dans le fichier donnees.csv
fdonnees.writerow(['numero','projet','URL','nombre_commentaires'])

#Ouverture du fichier avec les hyperliens des pages pour le scraping   
with open('fairemtl.csv', 'r', encoding = 'utf-8') as fURL:
    reader = csv.reader(fURL)

    #Passer au travers des hyperliens
    for url in reader:

        #Compteur pour suivre l'avancement du traitement
        compteur = compteur + 1

        #Afficher le compteur
        print('-'*60)
        print("Projet no.:             %s" % compteur)

        try:

            #Obtenir le code HTML de la page
            #Afficher l'URL de la page en traitement (pour du débuggage)
            print("URL:                    %s" % url[0])
            url[0] = url[0].strip() 
            #Mettre un délai pour ralentir le traitement (en secondes)
            time.sleep(5)            
            r = requests.get(url[0])

            #Afficher le code HTML de la page
            #print(r.content)

            #Mettre le contenu de la page dans BeautifulSoup
            soup = BeautifulSoup(r.content, 'html.parser')
            #print(soup.get_text())

            #Extraction des données
            #1. Extraire le nom du projet
            projet = soup.find_all("h1")
            projet2 = projet[0].getText().strip()
            print("Titre du projet:        %s" % projet2)           

            #projet = soup.title.string
            #projet = projet.string.replace(' | Faire Montréal','')
            #projet = projet.strip

            #projet3 = soup.find_all("title")
            #projet4 = projet3[0].getText().strip()
            #projet4 = projet4.string.replace(' | Faire Montréal','')
            #print("Titre du projet:        %s" % projet4)

            #projet5 = soup.find("meta", {"name":"title"})['content']
            #projet6 =  projet5[0].getText().strip()            
            #print("Titre du projet:         %s" % projet6)

            #2. Extraire le nombre de commentaires
            onglet_commentaires = soup.find_all("a",{"href":"#tabs-0-footer-2"})

            #2.1 Extraire le chiffre du libellé de l'onglet
            for item in onglet_commentaires:
                nombre_commentaires1 = re.findall(r'[0-9]+', item.text)
                nombre_commentaires2 = nombre_commentaires1[0]

                #Afficher le nombre de commentaire (pour du débuggage)
                print("Nombre de commentaires: %s" % nombre_commentaires2)  

            #Écrire les données dans le fichier donnees.csv
            fdonnees.writerow([compteur, projet2, url[0], nombre_commentaires2])

        except:
            pass

#Fermer les fichiers            
fURL.close()
#fdonnees.close()

#Fin du traitement
print('-'*60)
print("Traitement terminé.")
demandé 8-Jul-2015 par PascalRobichaud (124 points)

Poste ton code dans ta question, ça évite d'aller se taper du google doc.

Si je fais, avec la page https://fairemtl.ca/fr/24h-linnovation-volet-ville-intelligente un

print(r.content)

ça fonctionne.

Mais si je fais un

print(r.text)

ça ne fonctionne pas...

D'autres tests semblent indiquer que c'est un problème d'encodage.

J'ai forcé

r.encoding = 'utf-8'

1 Réponse

+2 votes

cela ne va pas t'aider, dsl, mais
- à partir de ton code posté dans la question
- de ton fichier .csv de ton dépôt google
j’obtiens:

>>>python3 test_www.py 
------------------------------------------------------------
Projet no.:             1
URL:                    https://fairemtl.ca/fr/affichage-dynamique-vers-stationnement-disponible
Titre du projet:        Affichage dynamique vers stationnement disponible
Nombre de commentaires: 0
------------------------------------------------------------
Projet no.:             2
URL:                    https://fairemtl.ca/fr/24h-linnovation-volet-ville-intelligente
Titre du projet:        24h de l’innovation - volet ville intelligente
Nombre de commentaires: 0
------------------------------------------------------------
Projet no.:             3
URL:                    https://fairemtl.ca/fr/ajout-services-publics-numeriques
Titre du projet:        Ajout de services publics numériques
Nombre de commentaires: 0
------------------------------------------------------------
Traitement terminé.

donc ça marche...

répondu 8-Jul-2015 par Lhassa (798 points)

Merci

Au moins, ça me dit que le code fonctionne.

Je vais essayer sur un autre ordinateur pour voir.

Tu es sur Windows, Mac, Linux???

J'ai essayé sur mon autre ordinateur et j'ai aussi le problèeme :-(

je suis sous linux... (re-testé à l'instant via un wifi sécurisé : réseau européen eduroam)
et je reconfirme que cela marche pour moi...

unicodecsv.VERSION (0, 13, 0)
bs4.__version__ '4.4.0'
requests.__version__  '2.2.1'

Merci

Je suis sur Window 7.

Refais des tests ce matin, il semble que se sont les caractères accentués qui causent le problème.

Je continue mes vérifications.

...