Home > Net >  How to handle exceptions while scraping multiple urls with slightly different structure?
How to handle exceptions while scraping multiple urls with slightly different structure?

Time:04-03

I want to create a dataframe after web scraping thousands of similar pages like this: https://questions.assemblee-nationale.fr/q9/9-64745QE.htm.

One of the columns that I want to create is "question" that I obtain from doing

right=soup_data.findAll('td', {'colspan': '2'})
question=right[8].quest.text

However there are a few exceptions (https://questions.assemblee-nationale.fr/q9/9-64743QE.htm) and in those cases the right code is:

right=soup_data.findAll('td', {'colspan': '2'})
question=right[9].quest.text

Is it possible to change my code, so that he handles these exceptions and does not interrupt every time that it finds an exception?

Here is my code:

import pandas as pd
from requests import get
from bs4 import BeautifulSoup as Soup
import numpy as np

question=[]
df = pd.DataFrame(list(zip([question])), columns =['Question'])

urls=["https://questions.assemblee-nationale.fr/q9/9-64741QE.htm",
"https://questions.assemblee-nationale.fr/q9/9-64745QE.htm",
"https://questions.assemblee-nationale.fr/q9/9-64743QE.htm"]
for url in urls:
    url=get(url)
    requests=url.text
    soup_data=Soup(requests, 'html.parser')
    right=soup_data.findAll('td', {'colspan':'2'})
    question = right[8].quest.text
    xf = pd.DataFrame(list(zip([question])), columns =['Question'])
    df = pd.concat([df,xf], axis=0)

CodePudding user response:

Selecting things by index is only an idea, if you know that it always exists in your whole process.

You are close to your goal but should change your strategy and select your elements more specific e.g. by element:

soup_data.find('quest').text

Also important check if element exists and handle that behavior:

  • try/except

    try:
        question = soup_data.find('quest').text
    except:
        question = None
    
  • if statement

    question = s.text if(s := soup_data.find('quest')) else None
    

Note: In newer code avoid old syntax findAll() instead use find_all() - For more take a minute to check docs

Example

import pandas as pd
import requests
from bs4 import BeautifulSoup as Soup

questions=[]

urls=["https://questions.assemblee-nationale.fr/q9/9-64741QE.htm",
"https://questions.assemblee-nationale.fr/q9/9-64745QE.htm",
"https://questions.assemblee-nationale.fr/q9/9-64743QE.htm"]
for url in urls:
    r = requests.get(url)
    soup_data=Soup(r.text, 'html.parser')
    question = s.text if(s := soup_data.find('quest')) else None
    questions.append(question)
    
pd.DataFrame(questions, columns =['Question'])

or to get more than this single information:

data.append({
        'analyse':s.text if(s := soup_data.find('ana')) else None,
        'question':s.text if(s := soup_data.find('quest')) else None,
        'response':s.text if(s := soup_data.find('rep')) else None
    })

Output

analyse question response
Fonctionnement. regroupement de policiers de plusieurs communes M Henri Bayard attire l'attention de M le ministre de l'interieur et de la securite publique sur l'interet qu'il y aurait, en particulier dans les communes rurales, de permettre aux policiers municipaux de se regrouper pour exercer leur mission en dehors du territoire de leur propre commune d'affectation. En effet, certaines missions, par exemple de nuit, necessitent la presence d'au moins deux personnes pour des raisons de securite evidentes, comme cela se passe dans la gendarmerie, et, dans la grande majorite des cas, la commune ne possede qu'un seul policier municipal. Il lui demande si la reflexion a ete menee sur ce sujet et quelles dispositions pourraient etre envisagees. Reponse. - S'il est souhaitable que les communes puissent recourir a de nombreuses formules de cooperation intercommunale, ce droit ne saurait leur etre accorde sans risques, y compris pour les libertes, dans le domaine de la police, compte tenu de ce que le bon exercice de celle-ci ne s'accommode ni du rapprochement des points de vue lorsqu'une decision urgente est a prendre ni de la dilution des responsabilites. Pour pallier ces risques, l'exigence de concentrer les pouvoirs de police entre les mains d'un responsable unique du groupement intercommunal ne manquerait pas tres rapidement de prevaloir, en fait dans un premier temps, en droit dans un second, ayant pour consequence de retirer aux maires des communes membres du groupement la direction et le controle des agents municipaux places sous leur autorite. C'est pourquoi il n'est pas envisage de mettre en place une institution qui remettrait en cause le principe de specialite territoriale applicable aux communes en matiere de police et qui battrait en breche celui selon lequel le pouvoir de police ne se delegue pas. Certes, en zone rurale, eu egard aux difficultes que rencontrent certaines communes pour s'assurer le concours d'un garde champetre, dont la presence est bien utile, compte tenu de la multiciplite des taches que le maire peut lui confier, ces principes peuvent etre quelque peu assouplis. Et c'est pourquoi l'article R 131-1 du code des communes accorde le droit aux communes d'avoir un meme garde champetre en commun. Mais ce droit, qui vise une situation bien specifique, ne saurait etre modifie en vue de permettre aux communes de creer des groupements d'agents de police municipale.
Federation francaise. fonctionnement. licenciements. cadres techniques M Jose Rossi attire l'attention de Mme le ministre de la jeunesse et des sports sur la situation des cadres techniques de la federation francaise de canoe-kayak. Ce corps de techniciens cree en 1960 a permis de mettre en place une structure efficace d'un sport qui a obtenu d'excellents resultats aux jeux Olympiques de Barcelone. En outre, le canoe-kayak, en particulier l'ensemble de ses cadres techniques, contribue a la lutte pour la defense de l'environnement, a la creation de nouveaux equipements et de nouvelles structures d'accueil pour les jeunes ; il participe egalement avec les collectivites locales au developpement touristique des zones rurales. Compte tenu de la menace de suppression de quatre-vingt-quatre postes qui pesent sur cette profession, il lui demande quelle politique elle entend mettre en oeuvre pour au contraire eviter le demantelement de cette activite tres importante pour le monde sportif francais. Reponse. - Le ministere de la jeunesse et des sports comme d'autres departements ministeriels contribue a l'effort budgetaire de reduction des effectifs de la fonction publique. Cependant, il convient de remarquer que la norme de reduction arretee a 1,5 p 100 en 1993 ne s'applique pas a ce departement ministeriel, considere par le Gouvernement comme un secteur prioritaire. En effet, le nombre d'emplois budgetaires a supprimer a ete fixe a quatre-vingt-dix au lieu de cent treize repartis de la maniere suivante : six emplois administratifs, quatre-vingt-quatre emplois de cadres techniques. Par ailleurs, les suppressions d'emplois sont compensees dans la loi de finances, a la fois par la creation de vingt contrats de haut niveau pour les entraineurs des federations non olympiques et par l'inscription d'une mesure budgetaire nouvelle dont l'objectif est de donner aux federations concernees par les retraits d'emplois les moyens financiers de recruter des animateurs sportifs. Ainsi, ce nouveau dispositif qui consiste a transformer pour partie l'aide actuelle en personnels par une aide financiere equivalente preserve les effectifs d'encadrement des federations en leur donnant une plus grande liberte quant au choix des personnels a recruter.
Livre : Suicide mode d'emploi. poursuites judiciaires. perspectives M Jacques Barrot appelle l'attention de M le garde des sceaux, ministre de la justice, sur les poursuites engagees depuis mars 1990 contre l'editeur du livre « Suicide, mode d'emploi ». Les services de la chancellerie ont precise que l'information suivait son cours au tribunal de grande instance de Paris et que le juge d'instruction envisageait a bref de clore son dossier. Il lui demande en consequence de le fixer sur l'etat de la procedure engagee en 1990. Reponse. - Les suites judiciaires donnees a l'ouvrage Suicide, mode d'emploi ainsi que l'expose des moyens mis en oeuvre par les services publics pour lutter contre le suicide des jeunes figurent dans les reponses du garde des sceaux, faites a differentes questions ecrites et publiees au Journal officiel de l'Assemblee nationale des 24 fevrier 1992, pages 2357 et 2358, et du Senat, le 24 septembre 1992, page 2196. Depuis lors, l'information suit son cours au tribunal de grande instance de Paris et le juge d'instruction designe, envisage, dans les toutes premieres semaines de l'annee 1993, le reglement de cette procedure. Par ailleurs, en ce qui concerne l'ouvrage intitule Final Exit, le garde des sceaux est en mesure de faire connaitre aux auteurs des questions ecrites que le tribunal correctionnel de Paris, par jugement du 15 decembre 1992, a, sur le fondement des articles 318-1 et 318-2 du code penal resultant de la loi no 87-1133 du 31 decembre 1987 qui incrimine le delit de provocation au suicide, condamne le president-directeur general de la societe Inter-Forum a la peine de 30 000 francs d'amende et a ordonne la confiscation et la destruction des ouvrages saisis.

CodePudding user response:

Might not be the best practice but a quick solution could be:

import pandas as pd
from requests import get
from bs4 import BeautifulSoup as Soup
import numpy as np

question=[]
df = pd.DataFrame(list(zip([question])), columns =['Question'])

urls=["https://questions.assemblee-nationale.fr/q9/9-64741QE.htm",
"https://questions.assemblee-nationale.fr/q9/9-64745QE.htm",
"https://questions.assemblee-nationale.fr/q9/9-64743QE.htm"]
for url in urls:
    url=get(url)
    requests=url.text
    soup_data=Soup(requests, 'html.parser')
    try:
      right=soup_data.findAll('td', {'colspan':'2'})
      question = right[8].quest.text
    except AttributeError:
      right=soup_data.findAll('td', {'colspan': '2'})
      question=right[9].quest.text
    xf = pd.DataFrame(list(zip([question])), columns =['Question'])
    df = pd.concat([df,xf], axis=0)
  • Related