Inscris-toi
(c'est gratuit !)
Un compte est nécessaire pour participer aux discussions.
Créer un comptelive_helpToutes les questions

Loudo
9 mars 2024
Résolue
3 réponses
Le print du bloc except ne s'affiche pas
Bonjour à tous,
J'ai voulu reproduire les bonnes pratique du try/except de la vidéo. Je met une mauvaise url pour produire l'erreur. J'ai bien l'erreur qui se lève mais le print du bloc except ne s'affiche pas !?! J'ai l'impression que c'est tout bête mais je n'arrive pas à trouver pourquoi ?
Voilà le code, j'utilise VS Code sous macOs.
```python
import requests
from bs4 import BeautifulSoup
BASRE_URL = "hfergerttps://books.toscrape.com/index.html"
def main():
try:
response = requests.get(BASRE_URL)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Problème avec l'accès au site: {e}")
raise requests.exceptions.RequestException from e
soup = BeautifulSoup(response.text, "html.parser")
if __name__ == "__main__":
main()
```
l'erreur que j'ai :
```
File "//Scrapping_cours_docstring/scrapping-02/main.py", line 15, in main
raise requests.exceptions.RequestException from e
requests.exceptions.RequestException
```
00:00:00 :Dans cet exercice, cette fois-ci, le but du libraire est d'enlever de sa page d'accueilles livres qui ne sont pas bien notés, à savoir les livres qui n'ont qu'une seule étoile.
00:00:09 :Vous voyez ici sur la page d'accueil, par exemple, on a sur la première ligne uniquementdéjà deux livres qui n'ont qu'une étoile, on en a un autre ici, un autre ici à la troisième ligneet peut-être un autre, oui, deux autres également à la dernière ligne.
00:00:21 :Donc le but du libraire, c'est de montrer sur sa page d'accueil uniquement des livres bien notéset donc on veut lui spécifier quels livres sur sa page d'accueil quand il publie des nouveaux livressont problématiques.
00:00:33 :Donc le but ici, ça va être de récupérer ces livres et de ne pas seulement récupérer le nommais également l'identifiant de ces livres.Alors si je fais un clic droit sur le nom du livre, vous allez voir que dans le lien vers le livre,on a donc catalogue slash le nom du livre en slug, donc avec que des lettres minuscules
00:00:50 :et des tirés entre les espaces et on a après, juste après ici, un tiré du bas et un numéroà trois ou quatre chiffres.Les livres, il y en a mille, donc ça va jusqu'à mille.
00:00:59 :Si je prends le premier ici, je crois que c'est le numéro mille, voilà.Et on descend comme ça, mille, neuf cent quatre-vingt-dix-neuf, etc.Donc ils sont en ordre décroissant.
00:01:06 :Et nous, ce qui nous intéresse, c'est donc de récupérer en plus du livre cet identifiantpuisque le but ici serait de passer par la suite automatiquement ces identifiantsà l'API du libraire qui lui permettrait d'exécuter ce script tous les jourspour enlever de son site de façon automatisée les livres, les nouveaux livres
00:01:23 :qui ont été ajoutés à sa librairie et qui ne comportent qu'une seule étoile en page d'accueil.Donc on a deux choses à récupérer ici.Déjà, les livres qui n'ont qu'une seule étoile et ensuite, sur ces livres spécifiquement,le numéro, l'identifiant ici qui est un nombre qui peut aller de un à mille.
00:01:37 :Donc si je vais plus loin sur les pages, par exemple si on va sur la page quarante-cinq,je vais aller ici sélectionner le dernier livre.
00:01:43 :Là, vous voyez qu'on a un index de cent-un.On va aller encore un petit peu plus loin et on va voir si on a un padding,ce qu'on appelle un padding.
00:01:50 :Donc par exemple, est-ce qu'on a zéro, cent-un, zéro, zéro, quatre-vingt-dix-neuf, etc.Et vous voyez que ça ne semble pas être le cas.Donc on a un nombre ici, un identifiant du livre qui va pouvoir comprendrede un à quatre chiffres, donc de un à mille.
00:02:03 :Et donc, il va falloir récupérer cette information.Une autre chose qu'on va rajouter dans cet exercice, c'est la gestion des erreurspuisque sur mon site, on va considérer que le libraire,il arrive en fait que quand le stagiaire met des nouveaux livres en place,il oublie parfois des informations et que des fois, on n'est pas ici le nombre d'étoiles
00:02:22 :ou qu'on n'est pas l'identifiant ou d'autres choses comme ça.Donc par exemple, là, je reviens sur mon inspection.On pourrait avoir une URL ici qui ne contient pas l'identifiant du livre.
00:02:30 :Et donc dans ce cas-ci, je veux pouvoir notifier le libraire qu'il y a un problème,non pas uniquement d'avertir le libraire qu'il y a des livres avec une étoile en page d'accueil,mais également si jamais il y a le moindre problème que ce soit sur cet affichage.
00:02:43 :Donc si on n'arrive pas à récupérer ces informations,si on a le moindre problème lors de l'exécution du script,je veux pouvoir avertir le libraire et donc je veux faire planter le scriptpour qu'il puisse voir qu'il y a eu un problème.
00:02:54 :Donc là encore, il y a plusieurs façons de faire.Je vous redirige vers nos deux articles.L'article sur la méthode EAFP et l'article de glossaire sur la méthode LBYLque vous retrouverez donc sur le glossaire de Docstring.
00:03:08 :Donc LBYL, look before you leap,qui consiste à utiliser plutôt des structures conditionnellescomme des if à la place du try except,et le EAFP, easier to ask for forgiveness than permission,qui lui à la place va utiliser des blocs try except plutôt que des if else.
00:03:25 :Donc je vous laisse lire ces deux articlessi vous voulez en savoir plus sur ces deux façons de faire.Moi, vous allez voir que dans ma solution, je vais privilégier les blocs try except.
00:03:33 :Et donc je vous laisse avec toutes ces informationset on se retrouve tout de suite pour ma solution à cet exercice.Alors comme d'habitude, la première chose qu'on va faire,c'est importer les bibliothèques dont on a besoin,donc Request et Beautiful Soup comme d'habitude.
00:03:46 :Et on va refaire notre structure de base,donc avec le main et le main ici qui va appeler cette fonction main.Donc jusque là, rien de bien compliqué.
00:03:54 :Et je vais ici faire une requête toute simple vers la page d'accueil.Donc puisqu'on ne veut pas aller au-delà de la page d'accueil,on veut juste vérifier cette URL.
00:04:03 :Donc je reprends l'URL de la page d'accueilet je fais une requête, donc un request.get pour récupérer la réponse.On fait un objet Beautiful Soup, là encore rien de bien compliqué.
00:04:12 :On va donner le response.text et on va mettre le html.parser.Alors première chose qu'on va faire ici,c'est gérer le cas de figure dans lequel on a une erreur avec cette requête.
00:04:23 :Donc là, ce que je peux faire, c'est un response.raiseForStatuset raiseForStatus, ça va me retourner une erreur,lever une erreur en fait, pas juste la retourner.
00:04:31 :Si on va voir la définition de cette fonction,vous allez voir que si on tombe sur un status code,donc un code de statut qui nous est retourné,qui est entre 400 et 500 ou 500 et 600,on va faire un raise, donc lever une erreur,httpError, qui hérite de requestException.
00:04:46 :Donc nous, on va faire un bloc tryExceptpour vérifier dans quel cas on tombe sur cette erreur.Donc ce que je vais faire ici, c'est un try pour essayer cette requête.
00:04:55 :Ensuite, on fait un response.raiseForStatusqui va lever une erreur si on a un code de statutqui nous est retourné entre 400 et 600.Et là, on va cibler le request.exceptions.requestException.
00:05:08 :Donc c'est l'exception qui nous indiquequ'il y a eu un problème avec la requête.Et qu'est-ce que je vais faire ici ?Eh bien, je vais lever de nouveau cette erreur.
00:05:16 :Donc vous allez voir qu'on va faire ça souvent dans ce script.Alors pourquoi on lève de nouveau cette erreur ?Alors là, il y a beaucoup d'étudiants dans ces cas de figurequi ne savent pas exactement ce qu'il faut faire.
00:05:25 :Qu'est-ce que je dois faire quand j'ai une erreur ?Eh bien, j'ai envie de vous dire qu'en fait, comme d'habitude,il n'y a pas une seule bonne réponse.
00:05:31 :Puisque ça va dépendre de ce que vous voulez faire.Est-ce que dans ce cas-ci, vous voulez considérerqu'il y a un problème avec la requêtemais que ce n'est pas grave ?
00:05:38 :En fait, on va aller sur une autre solution,une solution alternative.On va par exemple utiliser une API potentiellequ'on pourrait avoir ou faire d'autres choses.
00:05:46 :Ou alors vous considérez que c'est foutu,si on n'arrive pas à faire cette requête,eh bien, ça ne sert à rien d'aller plus loin.Là, dans ce cas, c'est exactement ça qu'on va faire.
00:05:54 :Par contre, on va quand même avertirle propriétaire de la librairie qu'on a eu un problème.Ça peut être en effet une information très importantepour la personne de savoir qu'on n'a pas réussià faire une requête réussie vers son site.
00:06:05 :Il y a peut-être un autre problème sur le sitequi fait qu'il n'est pas accessible au momentoù on lance le script.Donc, qu'est-ce que je veux faire ici ?
00:06:11 :Je veux lever une erreur et je veux avertirl'utilisateur qu'il y a eu un problème.Donc là, dans ce cas-ci, je vais faire juste un print.
00:06:18 :Mais imaginez qu'on puisse faire un envoi d'emailou qu'on puisse appeler une autre APIou faire quoi que ce soit qui va déclencherune alerte quelque part.
00:06:25 :Dans ce cas-ci, je vais juste faire un print.Je vais dire ici print et on va direqu'il y a eu un problème lors de la requête.
00:06:31 :Il y a eu un problèmelors de l'accès aussi, tout simplement.Et qu'est-ce que je vais faire une foisque j'ai alerté la personne avec un simple printqu'il y a eu un problème ?
00:06:41 :Eh bien, on va de nouveau faire un raise.Donc, raise qui va lever une exception.Puisque là, si je ne fais rien,si je mets juste le print, en fait,la requête ne va pas réussir.
00:06:50 :Mais ensuite, on va continuer avec le script.C'est ce qui nous est indiqué ici.Et si j'affiche les avertissements,là vous voyez qu'on a une variable locale responsequi est référencée avant un assignement.
00:07:01 :Donc le problème ici, c'est que si on passedans le except, response ne va pas être défini.On va essayer ça ici, mais s'il y a une erreur,on ne va pas déclarer cette variable.
00:07:10 :Et par la suite, si on fait juste mettreun print ici, on va passer sur cette ligneet on va essayer d'utiliser response.Et donc, on aura une erreur puisque ça va nous direque response n'est pas définie.
00:07:19 :Je peux vous le montrer ici.Si je modifie par exemple HTTPS ici,que je mets une autre chaîne de caractère,ça va provoquer une erreur.
00:07:26 :Et si je lance mon script ici,vous allez voir qu'on a un bound local error.Donc ça veut dire que la variable icin'est pas définie.
00:07:33 :Et on a également le print qui nous affichequ'il y a eu un problème lors de l'accès au site.Donc là, ce qui est bien important,c'est après ce print, de lever l'erreur de nouveau.
00:07:40 :Donc on va faire pour ça un raiseet on va indiquer qu'il y a eu un problèmeet on va lever la même erreur.Donc request.exception,
00:07:48 :donc request avec un S,.exception, .request exception.Et là, on peut également lier les deux erreurs ensemble.Si je fais juste ça ici,je vais remettre dans mon HTTPdes chaînes de caractère aléatoirespour que ça plante.
00:08:00 :Si je fais juste ça,vous allez voir que quand je lance le script,là on a un request exception error,donc c'est normal.Et on a ici l'autre exceptionqui est un invalid schema.
00:08:09 :Et il n'y a pas vraiment de lien entre les deux.Si par contre, ce que je fais,c'est que je récupère cette erreur,on va la récupérer en faisant un as e,et donc là e c'est une variable,on pourrait mettre error,on pourrait mettre Patrick,on peut mettre n'importe quoi.
00:08:21 :En général, vous allez souvent voirla lettre e qui va être utilisée.Et là, ce qu'on peut faire,c'est faire un from e.Donc là, vous allez voir la différence,c'est que si je relance le script,là vous allez voir qu'il y a une différence.
00:08:31 :En fait, il nous dit que l'exception au-dessus,donc cette exception invalid schema,était la cause directe de l'exception qui suit.Donc l'exception qu'on a rajoutée,request exception,qui nous indique qu'il y a eu un problèmelors de l'accès au site.
00:08:42 :Si j'enlève cette information ici,vous allez voir que le message va être différent.On n'aura pas de lien entre les deux.Donc si je relance,là vous voyez que ça nous dit que,lors du handling,donc lors du processus qui a fait cette exception,on a une autre exception qui est arrivée.
00:08:58 :Another exception.Donc vous voyez,là il ne fait pas le lien entre les deux.Il dit, ok, là on a eu un problème avec cette requête,donc on a levé une erreur avec le raise for status,qui a débouché sur cette request exception.
00:09:10 :Et nous ensuite,on a levé une autre exception,raise request,mais quand on ne met pas le from e,comme on l'a fait il y a quelques instants,il considère ces deux erreurs comme séparées.
00:09:19 :Il y a eu un premier problème ici,et on fait un autre problème ici.Donc là dans ce cas-ci,c'est important de mettre as e et from e,parce qu'on va dire que ce problème ici,ce request exception,il est lié directement à ce premierqu'on a provoqué en fait avec le raise for status.
00:09:35 :Donc c'est bien important là,quand on va faire du debug,de voir que les deux problèmes sont liés.On n'aurait pas de problème si on faisait juste un return,puisque là si je relance le script,eh bien on ne va pas lever une erreur.
00:09:45 :On aura juste le print qu'on a fait,et on a juste le script qui continue,dans ce cas-ci qui fait juste un return,mais on ne lève pas une nouvelle exception.
00:09:52 :Donc vous voyez,il y a différentes façons de gérer les choses.On peut la gérer avec un try except,en disant en cas d'erreur,on fait quelque chose et on continue le script.
00:10:00 :Donc soit on le continue là avec un return,ou alors comme je vous disais,on peut faire quelque chose d'autre.On peut dire ici,comme je vous disais,aller chercher les informationsà partir d'une API ou quoi que ce soit d'autre.
00:10:09 :Là dans ce cas-ci,ce qu'on souhaite,c'est pas continuer comme si de rien n'était,on veut vraiment qu'il y ait une erreur.On veut également avertir la personne,donc c'est pour ça que là on fait le print,et on relève l'erreur,mais en indiquant,donc avec le as-e et le from-e,
00:10:20 :qu'on veut bien lier les deux informations ensemble.Et le e ici,également,il va contenir l'erreur.Si jamais vous voulez le mettre dans votre print,vous pouvez très bien faire un fstring ici,je mets un f,et on peut dire ici,avec des accolades,qu'on va mettre l'erreurà l'intérieur de notre message d'erreur.
00:10:35 :Et si je relance le script,vous allez voir que cette fois-ci,on a bien le message qui nous ditque cette erreur a provoqué l'erreur juste en dessous,et là on a bien le message,il y a eu un problème lors de l'accès au site,no connection adapters were found for,
00:10:48 :et tout ça.Et donc ça,on peut comme ça envoyer ce messageà quelqu'un qui est chargé de la maintenance du site,pour l'avertir qu'il y a eu un problèmelors du scrapping du site.
00:10:56 :Donc moi,je vais laisser ça comme ça,là comme ça,on a une gestion bien faite des erreurs,selon le cas de figure là encore,une fois je le précise,de ce que je souhaite faire.
00:11:05 :Et là,vous voyez que l'avertissement sur response a disparu,puisque si jamais on ne récupère pas l'objet response,on ne va pas plus loin,on fait planter le script,et donc on n'aura jamais le problèmed'arriver ici avec un response qui n'est pas défini.
00:11:17 :Ce que vous pouvez faire aussi,c'est mettre ce code dans un else,le else ne sera exécuté que si le try a réussi.Donc là,c'est à vous de voir,ça peut être plus explicite de direque ce code en fait dépend directementde la réussite de celui-ci,c'est plus clair avec un else,
00:11:31 :après ça fait des niveaux d'indentation en plus forcément.Donc c'est à vous de voir,moi je pense que là,comme j'ai mis un raise,et que j'ai juste ce cas de figurequi est pris en compte,je vais juste mettre tout ça à la suite,puisqu'on va avoir pas mal de code
00:11:43 :qui va continuer après ça,après la récupération de la requête.Donc ici, qu'est-ce que je fais ?Je récupère mon soupe,comme d'habitude,à partir du response.text,
00:11:53 :et ce qu'on va faire,c'est récupérer les élémentsqui n'ont qu'une seule étoile.Donc si je retourne sur mon site,on va refaire un petit inspect avec un clic droit,on va essayer de voirqu'est-ce qui nous permet de vérifierqu'un élément n'a qu'une étoile.
00:12:05 :Donc là on voit qu'on a,même sur un élément qui n'a qu'une étoile,on a quand même 5 balises i ici,donc on ne va pas pouvoir compterle nombre de balisespour voir combien il y a d'étoiles.
00:12:14 :Par contre, si on remonte sur le p,là on voit qu'on a une classe star rating,et qu'on a un mot en toutes lettresqui nous indique le nombre d'étoiles qu'on a.
00:12:22 :Si je vais voir sur l'élémentpar exemple qui a 3 étoiles ici,on voit que là on a 3qui indique qu'on a bien 3 étoiles.
00:12:27 :Donc on va pouvoir se baser là-dessus,on va pouvoir tout simplement chercherles éléments qui contiennent ces deux classes,donc je vais faire un ctrl F pour vérifier.
00:12:34 :Là on voit qu'on a un résultat sur 6,et si je me souviens bien,on avait effectivement vuqu'il y avait à peu près 6 livres,je vais les compter,là on en a 2 sur la première ligne,3, 4, 5 et 6.
00:12:44 :Oui, 5 et 6 c'est ça.Et si on les fait défiler,effectivement on devrait arriversur tous ces éléments.Donc effectivement,ça semble être suffisantpour pouvoir vérifier le nombre d'élémentsqui ont une seule étoile.
00:12:55 :Donc ce que je vais faire,c'est récupérer dans une variableque je vais appeler par exempleone star books,ces éléments avec un select,on va faire soup.select,
00:13:04 :là encore on pourrait faireun find all à la place,je vais rester sur l'utilisation du select.Et qu'est-ce qu'on va faire ?Et bien on va vérifierles classes .starrating et .one.
00:13:14 :Donc là on vérifie bien les deux,qu'on ait à la fois le star ratinget à la fois le .one.On met tout ça,on n'oublie pas la majuscule ici sur le one,et on va vérifier déjà ce que ça nous donne.
00:13:23 :Donc je vais faire un print de one star book,en fait on va même faire un printde la longueur de one star book,et normalement ici ça devrait nous retourner 6.
00:13:30 :Je vais également remettre en forme mon httpspour pas qu'on ait d'erreur,je relance,et là on a bien 6 qui est affiché,donc c'est exactement ce qu'on s'attendait à avoir.
00:13:38 :Maintenant qu'est-ce qu'on va faire ?On va vouloir récupérer,comme je vous disais,on arrive à la deuxième partie,on va vouloir récupérer l'identifiantde ces livres pour pouvoir le passerà un script qui fera automatiquementle travail de les enlever de la page d'accueil.
00:13:50 :Donc l'identifiant il est dans l'URL,si je me souviens bien,on va voir ici,effectivement on a le 999 ici,alors je vais voir s'il n'est pas ailleurs quand même,on va essayer de chercher 999,et il est effectivement à un autre endroit,donc on a le A ici qui correspond à l'image,
00:14:06 :et on a le A du H3.Donc moi je suis sur le star rating ici,je pense que je vais,alors là on peut aller dans les deux directions en fait,on peut soit remonter à l'élément parent,donc le image container,à partir de cet élément P,pour récupérer ensuite l'URL à partir de là,
00:14:22 :ou alors descendre et récupérer le H3qui contient le A ici,et je pense que je vais plutôt me diriger vers le H3,parce que j'ai plus d'informations intéressantes,sur l'image ici,il faudrait que je récupère,si je veux récupérer en fait le titre,que je récupère également l'image,
00:14:37 :et ensuite l'attribut alt,alors qu'avec le H3,si je veux récupérer ici le titre,en fait je peux récupérer le texte,je peux récupérer l'attribut title,directement à partir du lien,donc j'ai plus d'informations ici au même niveau.
00:14:50 :Donc ce que je vais faire,c'est aller au prochain élément,et je vais préciser aussi mon code,puisque là en fait,j'ai mis directement tous les élémentsqui peuvent contenir StarRating1,je vais préciser en mettant le P ici,puisqu'on voit que sur cet élément ici,c'est un élément de paragraphe,
00:15:05 :donc ça va me permettre de vraiment êtrebeaucoup plus spécifique,sur les éléments qui contiennent ces classes.C'est toujours bien,là on a vu que c'était uniquement sur les livres,mais si jamais par la suite,je ne sais pas,on rajoutait,enfin le libraire rajoutait un élémentavec ses classes,
00:15:19 :sur par exemple un div,qui contiendrait la note moyennede tous les livres de la bibliothèque,et bien si on ne spécifie pas avec le P ici,ça irait récupérer tous les éléments,que ce soit des divs, des liens, peu importe,là on spécifie bien qu'on veut aller chercher
00:15:31 :le paragraphe.Donc maintenant que j'ai ça,j'ai une liste en fait,donc une liste de nœuds ici,dans mon soupe,je vais pouvoir boucler dessus,puisqu'on va vouloir chercher sur chaque livre,l'identifiant du livre,donc on va dire pour BookInOneStarBooks,et ici ce que je vais faire,c'est utiliser le FindNext,
00:15:48 :donc on va faire un print de Book.FindNext,vous allez voir que FindNext,ça permet de chercher le prochain élémentdans la hiérarchie,à partir de là où on est,donc là on va être sur le P ici,le prochain élément qui va correspondreà ce qu'on va donner comme élément ici,
00:16:02 :donc là dans ce cas-ci,on va chercher un H3,et ça va nous trouver le prochain H3qui est après le rating ici,donc je vais vérifier qu'on n'a pas d'autres H3 ici,mais ça ne semble pas être le cas,ici on a des i pour les icônes des étoiles,
00:16:15 :et après, directement après ici,on a le H3.Donc je vais dire FindNext,on va récupérer le prochain H3,je vais lancer le script avec le printpour voir ce que ça donne,et là voilà,on récupère bien donc le H3 avec le lien,et à l'intérieur de ce H3,
00:16:27 :eh bien du coup,je vais faire,on peut faire un Find,on pourrait faire le Select là encore,je vais faire juste un Findpour trouver l'élément unique,là on n'en a qu'un,on n'a qu'un seul lien,donc c'est ce qu'il nous faut.
00:16:37 :Donc je relance le script pour vous montrer,là on va descendre,on arrive au niveau du A,et ce que je veux moi,c'est récupérer le Href ici,l'attribut Href,donc là je vais faire un crochetavec le nom en chaîne de caractèrede l'attribut que je souhaite récupérer,
00:16:50 :et on va voir tout de suite aprèscomment on va pouvoir gérer les erreurs,pour l'instant je récupère les informations,et là ça fonctionne,on récupère bien l'URL en fait de chaque livre,et nous ce qu'il va falloir faire,c'est par la suite récupérer donc ce numéro.
00:17:02 :Donc pour l'instant,on va se concentrer sur la gestion d'erreurs,et par la suite on va voircomment on peut récupérer cet identifiantà l'intérieur de l'URL.
00:17:09 :Donc là ce que je vais faire,c'est créer une variable,on va l'appeler BookLink par exemple,et on va provoquer en fait les erreursqui peuvent arriver,puisque là il y a beaucoup de chosesqui sont enchaînées à la suite,on a le FindNext,on a le Find,et ensuite on a les crochets ici
00:17:22 :pour récupérer la valeur de l'attribut.Alors il y a plein de chosesqui peuvent ne pas fonctionner ici,et pour vérifier quel type d'erreur on aet les récupérer avec un bloc TryExcept,il faut provoquer ces erreurspour voir quel type d'erreur on peut avoir.
00:17:33 :On peut également les deviner,là dans ce cas-ci,quand on a des crochets comme avec un dictionnaire,ça va être probablement un KeyError,mais le mieux c'est de provoquer ces erreurspour voir les cas de figure qu'on peut avoiret les gérer.
00:17:43 :On pourrait également adopter une autre approche,l'approche LBYL,Look Before You Leap,qui serait un peu plus verbeuse ici,puisqu'en fait il faudrait décomposer chaque élément,donc par exemple,commencer par le FindNext,vérifier si on a quelque chose ici,si c'est le cas, donc faire un If,donc si on a quelque chose ici,
00:18:00 :on continue avec le Find,si on a quelque chose avec le Find,on continue avec le Href,et ainsi de suite.Moi je préfère ici adopter le EAFP,donc c'est plus facile de demander la permission,donc en gros on va faire toute cette ligne ici,on va faire tous ces éléments à la suite,
00:18:15 :et on va gérer les cas de figure qui peuvent arriver.Donc on va y aller un petit peu bourrin,on va dire ok, essaye de faire cette ligne,si ça marche tant mieux,ça veut dire qu'on a récupéré le lien,et par contre s'il y a eu tel type d'erreur,
00:18:25 :alors tu vas dire ça,s'il y a eu tel type d'erreur,tu vas faire ça,et on va gérer ça avec un bloc Try Except.
00:18:30 :Donc je mets le Try ici,j'essaye tout ça ici,et je vais mettre un Except,et là l'erreur que je vois la plus souvent,qui est une erreur très classique des débutants,c'est de faire un bloc Try Except simple comme ça,et par exemple ici de mettre un Continue,
00:18:44 :donc de dire si on n'a pas réussi à faire ça,on continue.Le problème de ça,c'est qu'on va masquer toutes les erreurs,donc là si je lance le script,je vais faire un print de BookLink ici,pour voir que dans ce cas-ci,on va bien récupérer les liens,
00:18:56 :donc je lance,ok ça fonctionne,on a les liens,par contre imaginez que je change,là je mets un H4,avec un script comme ça,en fait on ne va pas avoir les erreurs,on n'aura rien ici dans le output,mais on n'a pas d'erreur,donc là si on met un script comme ça,
00:19:07 :le libraire pourrait se dire,bon bah en fait ça va,je n'ai pas de livre avec une seule étoile,sur ma vitrine,donc je peux continuer ma vie tranquillement,le problème c'est qu'ici,en fait on voit bien que ce n'est pas le cas,il y a des livres qui n'ont pas,
00:19:19 :le nombre d'étoiles suffisant,mais comme on a masqué les erreurs ici,avec un Except et un Continue,on ne voit pas le problème,donc là ce qu'on va faire comme je vous disais,c'est à la place,vérifier quelle erreur on va avoir,donc je vais provoquer ces erreurs,alors qu'est-ce que je vais faire ici,
00:19:32 :à la place du Except,on va récupérer toutes les exceptions pour commencer,et on va refaire juste un Raise de exception,donc ça va permettre,avec l'exception ici,c'est l'erreur la plus générique,qui va couvrir toutes les exceptions possibles,en fait à part deux exceptions,si je me souviens bien,
00:19:47 :qui sont des exceptions,qui sont provoquées volontairement,donc quand on va par exemple,interrompre le script,si je lance le script,et qu'ensuite je fais un CTRL C dans le terminal,ça va provoquer un KeyError,quelque chose qui bord d'erreur,si je me souviens bien,et donc c'est des erreurs volontaires,
00:20:00 :mais toutes les autres erreurs,des erreurs qu'on pourra avoir avec des attributs,des KeyError, des ValueError,AttributeError, etc,ça va être récupéré par cette exception.
00:20:08 :Ce qu'on peut faire aussi,c'est enlever pour l'instant le bloc TryExcept,et juste remettre ces lignes avec l'indentation,lancer, et là on va provoquer cette erreur,donc on voit bien ici qu'on a un AttributeError,mais c'est un petit peu péniblede devoir enlever notre bloc ici,TryExcept qu'on a commencé à faire,
00:20:22 :donc à la place,je vais juste faire AcceptException,et refaire un Raise d'exception.Donc là si on lance,on va avoir notre exception qu'on a levée à la fin,et si on monte un petit peu,on voit l'exception qui a provoqué cette autre exception,donc c'est ici un AttributeError.
00:20:36 :Donc l'AttributeError,c'est en fait quand on va faire un Find,puisque là le FindNext ne va rien trouver,donc ici qu'est-ce qu'on va avoir comme résultat ?
00:20:43 :En gros, un None,et donc c'est comme si on faisait None.Find,et c'est exactement ce que ça nous dit ici,l'objet None n'a pas d'attribut Find.
00:20:49 :Donc là on va pouvoir gérer cette erreur précise,on va dire AcceptAttributeError,et comme vous vous souvenez,on va faire la même chose qu'auparavant,c'est-à-dire qu'on va dire que cette erreur,donc l'erreur qu'on va lever ici,découle de l'erreur d'AttributeError.
00:21:01 :Ce qu'on va faire, c'est juste entre-temps faire un Print,et dire par exemple ici,impossible de trouver la balise H3 ou la balise A.Et donc là j'ai mis H4 pour provoquer l'erreur,mais après on remettra la balise H3.
00:21:14 :Et si jamais on a cette balise H3 ou cette balise Aqui sont inexistantes,ça veut dire qu'on aura un problème.Et en fait non,je n'ai pas besoin de mettre la balise A,si je ne me trompe pas ici,puisque si on a un problème,donc si on trouve quelque chose sur le H3,
00:21:27 :et qu'en fait on a un problème ici,ça va être un autre problème.Donc avec les crochets ici,comme je vous ai dit,je pense que ça va être un KeyError.
00:21:34 :Mais en fait,le Find ici pourrait nous retourner un None aussi.Et donc dans le cas de None,Href,je ne suis pas sûr ce que ça va nous retourner.
00:21:43 :Donc là encore,je vais lancer le script.Et dans ce cas-ci,c'est un TypeError.Donc vous voyez qu'on a une autre erreur à gérer.Donc là,la première erreur qu'on peut avoir,qu'on a identifié,c'est sur ce segment ici,qui serait potentiellement égale à None.
00:21:54 :Et dans ce cas-ci,on a un AttributeError.Donc on a quelque chose sur le FindNext,mais que c'est après,ici,qu'on se retrouve avec le Findqui nous retourne None.
00:22:02 :Là,dans ce cas-ci,c'est un TypeError.Donc là,je vais pouvoir rajouter mon exception ici.Et je vais refaire,je n'oublie pas,de faire un RaiseAttributeErrorfrom E,ici.
00:22:12 :Et on va gérer donc le deuxième cas de figure.On va faire un AcceptTypeError as E.Là,on va dire qu'on a donc un problème.
00:22:18 :Donc on va dire,alors là,j'ai mis un IfString,mais je n'en ai pas besoin.Donc on va dire impossiblede trouver la balise Aà l'intérieur du H3.
00:22:26 :Et là,donc,on va tester.On va refaire un Raisede TypeError from E.Et là,donc,pour provoquer le problème,je vais mettre,par exemple,ici,une balise qui ne fait pas de sens.
00:22:39 :Je relance.Et là,on a bien le TypeError.Donc impossible de trouver la balise A.Donc,je vais mettre peut-être des guillemetspour que ce soit plus clairque c'est la balise A,comme ça.
00:22:48 :Et la balise H3,ici aussi,je vais mettre comme ça,la balise H3.Donc là,on va mettre H4 ici.Là,on a bien le AttributeErroravec le print,voilà,qui est quelque part ici.
00:22:59 :Donc,impossible de trouver la balise H3.Si je remets mon H3et que je relance,là,on va avoir cette fois-cile TypeError,impossible de trouver la balise A.
00:23:07 :Et le dernier,donc là,on va mettre autre chose.On va mettre une autre balisequi ne sera pas trouvée.Je relance.Et là,dans ce cas-ci,qu'est-ce qu'on a ?
00:23:16 :On a un KeyError.Donc,le KeyError,puisque comme je vous disais,en fait,ici,on peut faire un point Get.Comme je vous disais,la différence,c'est que le point Getne va pas lever d'erreurs'il n'y a rien.
00:23:28 :Donc,si je relance,là,vous voyez qu'on a juste None.Donc,c'est là encore,une fois,exactement comme avec les dictionnaires.Si on met Get,on n'a pas d'erreur.
00:23:38 :Si on met les crochets,donc,on aura une erreur.Et moi,c'est ce que je préfère.C'est provoquer,dans ce cas-ci,cette erreurdans le cas où l'attributn'est pas à l'intérieur de ce A.
00:23:48 :Donc,si on avait un lien videimpossiblede trouverl'attribut hrefet on refait un Raisede KeyErrorfrom E.Donc là,vous voyez,ça fait beaucoup de choses,mais on a tous les cas de figurequ'on a identifiéqui sont gérés.
00:24:03 :On a bien le KeyError ici.Si je remonte,impossible de trouver l'attribut href.Et donc,vous voyez,ça fait beaucoup de lignes de code,mais là,au moins,tous les cas de figure sont gérésavec à chaque fois un printqu'on pourrait modifier,comme je vous dis,pour faire,
00:24:16 :par exemple,un fichier de logou pour envoyerun messageà un site.Et je me répète,mais je le précise encore une fois,c'est à vous de déciderce que vous souhaitez faireavec ces erreurs.
00:24:26 :Vous n'êtes absolument pas obligésde refaire un Raise ici.Vous pourriez vous dire,ok,c'est pas grave,je n'ai pas trouvé l'informationque je veux ici,donc je n'ai pas trouvé le href,mais on va essayerd'autres cas de figure.
00:24:36 :On ne va pas faire de Raise,on va juste continuer le scripten vérifiant d'autres choses,en essayant de trouver l'informationailleurs sur la page,par exemple.
00:24:42 :Là,dans ce cas-ci,moi,je veux vraiment que ça provoque une erreurdans le cas où ces informationsne sont pas trouvées.Donc,on touche au but.
00:24:50 :Là,si je fais un Print,dans ce cas-ci,de Book Link,après ça,donc je vais enlever mon Print ici,je vais le faire après mon Block Try,je relance,et là,normalement,je crois que j'ai tout remis comme il faut,c'est bien.
00:25:02 :On a donc tous les liensdes livresqui n'ont qu'une seule étoile.Donc là,ce qu'il reste à faire,c'est de trouver cet élément iciqui va contenir de 1 à 4 chiffres.
00:25:09 :On l'a vu,les ID,donc les identifiants,vont de 1 à 1000.Et donc là,on va importer le modulequi va nous permettrede les faire.
00:25:19 :Donc pour ça,on le met tout en hautde notre script ici.On va faire Import Re,donc Regular Expression.On va le mettre avant Requestet Beautiful Soup,et séparer dans l'espacepuisque le module Refait partiede la librairie standard de Python.
00:25:30 :Et ensuite,Request et Beautiful Soup,ce sont des bibliothèquesqu'on a importées,qu'on a installéesen fait,avec Pip en plus.Donc,qu'est-ce que je vais faire ici ?
00:25:39 :Je vais vouloir chercherdans mes URL ici,l'identifiant.Alors là encore,il y a plein de façons de faire.On pourrait passer à traverschaque caractèrede la chaîne de caractèreset ne pas utiliserle module Regex,mais ça serait peut-êtreun petit peu lourdde devoir faire cette boucle
00:25:52 :à chaque fois.On peut essayerde supprimertous les caractèresqui ne sont pas juste des nombres,mais ça va poser problèmepar exemple,avec ce dernier exemplequi est très bien placépuisqu'on voit que là,on a Best Science Fictionentre 1800 et 1849.
00:26:04 :Donc là,on a le dernier élément,le dernier nombrequi est bienl'identifiant du livre,mais là,on a d'autres nombresqui ne sont pas liésà l'identifiant du livre.
00:26:13 :Donc là,on a un pattern,comme on diten bon franglais,un patternqui va être unique,qui va permettred'identifier cet identifiant.Comme je vous l'ai dit,ici, on a le slug.
00:26:23 :Les slugs,ça va contenirtoutes les lettressans les caractères spéciauxtout en minusculeset les espaces vont être séparéspar un tiret du milieu.
00:26:30 :Et nous,qu'est-ce qu'on voit ici ?À la fin,ça a été bien fait,on a un tiret du basqui sépare en faitle nombre icidu reste de l'URL.
00:26:38 :Alors,l'autre façon de fairesans les Regex,ce serait de faire des splits,donc de faire un splitpour récupérerce qui est au milieu.
00:26:46 :C'est une première façon de fairequi peut être assez intéressante,qui évited'utiliserles expressions régulièresqui peuvent êtreun petit peu compliquées.Moi, ce que je vais faire,c'est donc utiliserà la place ce module Re.
00:26:56 :Et pour ça,on va utiliserune expression régulièrequi va chercherun tiret du baset une suitede 1 à 4 nombres,précisément,donc entre 1 et 4,1, 2, 3 ou 4.
00:27:06 :Et on va chercherprécisément cette suitedans la chaîne de caractères.Donc soit un tiretavec un nombre,soit un tiretavec deux chiffres,soit un tiretavec trois ou quatre chiffres.
00:27:15 :Donc cette expression régulière,ici, je vais la fairedéjà dansune chaîne de caractères.Pour cibler les nombres,on va faireslash d.Pour ciblerle tiret du bas,on met tout simplementle tiret du bas.
00:27:26 :Et pour ciblerun nombre d'occurrencesentre 1 et 4,on va mettreun élémententreacolade,ce qui va nous permettreici, les acolades,de spécifierle nombre d'occurrencesqu'on souhaite avoir.
00:27:37 :Et pour spécifierle nombre d'occurrences,on met 1,4 comme ceci.Donc ça peut allerde 1 à 4,si on en a 2, c'est bon,si on en a 3, c'est bon,et si on en a 4,également, c'est bon.
00:27:46 :Et donc, on a icitoute notre expression régulière.Vous voyez que ça peut faireun petit peu peur.Si vous n'êtes pas habituéà aller voir des formationssur les expressions régulières,on en a sur docstring.
00:27:54 :Mais voilà,vous voyez que là,dans ce cas-ci,c'est une expression régulièreassez simple,donc c'est pour çaque j'aime bien l'utiliser.Et je vais mettre un r devantpour que ce soit bienun row string,donc pour qu'il n'y ait pasde caractères qui soientinterprétés différemment.
00:28:07 :Et ensuite,je vais donner tout çaà la méthode findAlldu module row,donc findAllqui va me permettrede trouver toutes les occurrencesde ce motifà l'intérieurde ma chaîne de caractères.
00:28:17 :Et je vais récupérer çapour l'instantdans une variableque je vais appelerbookId.Et on va lui passer ensuiteen deuxième argumentla chaîne de caractèresà travers laquelleon souhaite chercher,donc dans ce cas-ci,ça va être bookLink.
00:28:29 :Donc je ne vais pasaller plus loin,je vais faire un printde bookIdet on va voirce que nous retournece findAll.Je lance le scriptet on voit ce que ça donne.
00:28:38 :Et là vous voyez que,magie,on a bien une listeavec en premier élémentl'identifiant,donc qui contient icile tiré du bas,donc il va falloir l'enleverbien sûr,mais on a bien réussià trouver ce qu'il nous fallait.
00:28:49 :Là encore on va fairede la gestion d'erreurpuisque on pourrait avoirdes chaînes de caractèresqui ne contiennent pascette information.Donc je vais vous montrer,là encore on va provoquercette erreur,pour l'instant on va justerésoudre ce petit problèmepuisque là on a une listeavec un élément
00:29:02 :et on a le tiré du bas.Donc ce que je vais fairec'est de faire un print,c'est à dire qu'on considèreque tout marche bien,qu'on a tout ce qu'il nous faut,on récupère le premier élémentet ensuite on va refaireun crochet et faire un 2 points.
00:29:14 :Pourquoi on fait un 2 points ici ?Donc là encore on fait un slice,ça va être pour récupérertous les élémentsà partir du deuxième caractère.
00:29:19 :Donc on évite le premieret on prend tous les élémentsà partir du deuxième.Donc ce que je vais fairepour tester tout ça,pour vérifier que ça fonctionne bien,c'est refaire un printde mes URL,donc de Booklink ici,et je vais les mettredans une listepour juste vérifier
00:29:31 :avant que ça fonctionne bien.Donc j'ai tout ça,je vais en prendre un ici,donc le premier,et je vais recréeren fait ma variable icipour défairece qu'on a fait ici.
00:29:39 :Donc on pourrait le faireen dehors de cette fonctionpour ne pas faire un requestà chaque fois,d'ailleurs ce serait peut-êtreun peu plus simple.
00:29:45 :Donc je vais le faireà la place du main ici,je vais créer une variablequi est tout simplementcette chaîne de caractères,je vais me faireun petit peu de place aussi,et on va faire notre find allpour vérifierquel type d'erreuron peut avoir.
00:29:56 :Donc là si je faisun print de BookID,je lance mon script,qu'est-ce qu'on a ?On a bien 900 caractèresDonc ça fonctionne,là dans ce cas-ci,on a exactementle cas de figurequ'on souhaitait avoir,c'est-à-dire une URL valideavec le tiré du bas,999,on récupère l'identifiant
00:30:10 :et ensuite,comme je l'ai dit,on peut envoyercet identifiant à une APIqui va se chargerde retirer ce livrede la page d'accueil.
00:30:17 :Maintenant,qu'est-ce qu'il se passesi par exemple icion a 5 éléments ?Je vais mettre 44 devant,je relance,qu'est-ce qu'il se passe ?
00:30:24 :On a 4 4 9 9.Donc notre expression régulièrefonctionne puisqu'on a ditqu'on voulait de 1 à 4,donc là,ce n'est pas un identifiantqui est valideselon notre expression régulière.
00:30:32 :Si jamais on souhaitaitadapter notre expressionpour qu'elle fonctionneavec des bibliothèquesqui pourraient contenirpar exemple 150 000 livres,dans ce cas-ci,on peut enlever le 4et dire qu'il fautqu'il y en ait de 1à un nombre infini.
00:30:43 :Donc là,vous allez voir quesi je relance le script,cette fois-ci,on va bien récupérertous les nombresà l'intérieur de cette chaînede caractères,donc 44 999.
00:30:52 :Dans ce cas-ci,on n'avait que 1 000 élémentsdans notre bibliothèque,mais je pense que ça peut êtrebien de prévoir et se direque par la suite,on pourrait avoir par exemple10 000 livres sur la bibliothèqueet donc,on va enlever le 4pour gérer ce cas de figure.
00:31:03 :Imaginons maintenantque je n'arrive pasà trouver une occurrencede ce que je cherche.Par exemple,à la place du tiré du bas,on va mettre un tiré du milieu.
00:31:10 :Je relance et là,qu'est-ce qu'on a ?On a notre première erreur,index error,list indexed out of rangeet avec les dernières versionsde Python,en plus,on a un petit dessin iciqui nous indique très clairementoù est le problème,ce qui n'était pas le casavec les versions antérieures
00:31:23 :à la 3.11 ou 3.12si je me souviens bien.Les développeurs de Pythonont ajouté plein de petites chosescomme ça,c'est sympa.Avant,on nous disait justelist indexed out of rangeet on ne savait passi l'erreur était ici par exempleou sur le deuxième splicequ'on a ici.
00:31:37 :Donc là,c'est très clairque le problème se situe iciet donc,qu'est-ce qu'on a comme problème ?On a un problème de index errordonc on va pouvoir retourner icidans notre fonctionet gérer ce cas de figure.
00:31:46 :Donc,je vais enlever mon booklink,je vais décommenter çaet je vais faire un try,except,except en cas de index erroras e,on va dire print,donc là encore,on peut envoyer une alerte,on va dire impossiblede trouver l'idée du livre.
00:31:58 :Voilà.Et on va refaireun raise index errorfrom e.Et je vais enleverle 4 que j'avais ici.Donc,voilà pour cette erreurqu'on a géréeet avant de terminer,on va réfléchirà ce deuxième élément ici.
00:32:10 :Est-ce qu'on peut avoirune erreur dans ce cas-ci ?Alors,soit on n'a pas réussià récupérer quelque chose iciet dans ce cas-ci,l'erreur va êtresur le crochet 0 icidonc,l'erreur va êtresur le crochet 0 icidonc,le index errorqu'on vient de faire.
00:32:24 :Si par contre,on arrive à récupérerquelque chose,normalement,les splices icine devraient pas poser de problèmeparce que même si on récupèreen fait une chaîne videou une chaîne qui comprendplein d'autres choses,le slice va juste récupérertout ce qu'il y a.
00:32:36 :On va faire un test ici.J'ai un petit doutemais si je mets une chaînede caractère comme çaqui est vide,par exemple,je vais faire un printde tout çajuste pour vérifier.
00:32:45 :J'enlève le book ID.Je relance.Là,vous voyez qu'on n'a pas d'erreur.On peut faire à peu prèstout ce qu'on veutcomme ça avec un slicemême si,peu importe ce qu'on a en fait ici,je peux mettre une chaînede caractère,je peux mettre n'importe quoi.
00:32:58 :À chaque fois,vous allez voir qu'en fait,on va avoir un résultatet on n'aura pas d'erreur.Là,si j'enlève aussi,si je mets tout ça,on va avoir justeexactement la même chose.
00:33:07 :Si je mets un élémentqui finit ici,si je mets 40,moins 50,etc.Donc en fait,on ne peut pas faire planterle script icipeu importe ce qu'on récupèrecomme chaîne de caractère.
00:33:17 :Donc,si on n'a pas d'erreurd'index iciavec le crochet zéro,on va récupérerune chaîne de caractèrepuisque FindAllva nous retournerdes chaînes de caractèreet donc,on pourra faire le sliceà partir de ça.
00:33:30 :Donc après,bien sûr,on pourrait faired'autres vérificationspour s'assureravec notre APIà laquelle on enverraitcet identifiant,que l'identifiant est biendans la bibliothèque,etc.
00:33:41 :Mais là,ça sort du cadrede cet exercice.Donc là,vous voyez qu'on a un scriptqui est un petit peu plus long.C'est à dire,le scope,le select,le find next,ça représente peut-être4 ou 5 lignes de code maximummais là,au moins,ce qu'on a,
00:33:56 :c'est vraiment quelque chosequi va être 100% bulletproofcomme on dirait en bon français,c'est à dire qu'on va gérertous les cas de figurequ'on a pu identifierpour avertir les personnescompétentesdu problèmequ'on a eu lors du scrapping.
00:34:06 :Et donc,dans ce cas-ci,moi,ce qui m'intéressecomme on l'avait dit,c'était les book id.Donc,ce que je peux fairec'est tout simplement une liste.
00:34:15 :Donc là,je vais mettre dans le else,là,on va le lier,on va fairebookids.appendbookid.Donc là,je le mets dans le elsepour bien qu'on comprenneque c'est lié à ce try.
00:34:25 :Donc là,le else,en fait,va être exécutési on n'a aucune erreurqui se passe.Donc,si on passe dans le try,on va également passer dans le elseaprès être passé dans le try.
00:34:35 :Et à la fin,je vais tout simplement faireun return de bookidscomme ceci.Et on va mettredes annotations de typepour terminer,pour que ce soit bien clair.
00:34:43 :On va dire qu'on retourneà la liste.Donc,si je relance mon script,je vais faire un petit reformatde tout ça.Vous voyez qu'on aune quarantaine,une bonne quarantainede lignes de code.
00:34:53 :Là,on n'a pas refactoré,on a tout fait dans une seule fonction.On verra dans le dernier exercicequi va être pas mal plus longcomment on peut organiserbien mieux tout ça.
00:35:00 :Mais pour l'instant,je vais rester avec une seule fonction.Ici,on s'est plus concentrésur la gestion des erreurs.Donc,je relanceet on va voir si on a bience que je veux.
00:35:09 :Donc là,je n'ai pas fait de print,bien sûr,on pourrait là encoreles convertir en intsi on souhaitaiten faisant une petite conversionint icipour relancer.
00:35:19 :Voilà.Et là,on aurait tous les identifiantsen nombre entierdes livres qui posent problèmequ'il faudrait enlever.Et ça serait même plus raccordavec ce que j'ai mis icipuisque j'ai dit que je retournaisune liste de nombre entier.
00:35:29 :Donc,si je ne convertis pasen int ici,je vais avoir une différenceavec mon annotation de typeici qui indiquequ'on retourne bienune liste de nombre entier.
00:35:37 :Et là,avant de terminer,je viens de me rendre compteici qu'on peut simplifierl'expression régulièreen mettant un plus.Le plus,ça va être 1 à l'infini.
Ce n'est pas fini...
✋
Tu as complété % du parcours 🔥
Termine l'intégralité de la formation pour pouvoir débloquer ton attestation de réussite.