Bonjour tout le monde, j'ai un petit script me permettant de récupérer le nombre de connectés sur différents forums de JVC. Sauf que cette nuit, j'ai eu une erreur et n'ayant rien mis en place il s'est arrêté tout net et ma machine a tourné pour rien. pendant plus de 10 heures
J'ai donc un peu réfléchit à une sorte de gestion des erreurs qui dès lors je n'arrive pas à accéder à la page cela réessaie au bout d'un certain temps. Mais je ne sais pas du temps comment l'implémenter correctement. J'en ai déjà fait un (petit) mais dans ce schéma là je ne sais pas comment le faire. Je pense juste qu'il faudrait que je recupère le code de réponse HTTP via getcode et que cette gestion se fasse dans la fonction "recup_co"
Voici ma classe :
class Forum():
def __init__(self, forum, url_forum):
self.forum = forum
self.url_forum = url_forum
def add_to_database(self): #ajout au fichier de la BD, la date et le nb_co
connection = sqlite3.connect("database.db")
c = connection.cursor()
self.now = datetime.datetime.today()
self.text = "INSERT INTO {0}(datetime, nb_co) VALUES('{1}', '{2}')".format(self.forum, self.now, self.recup_co())
print(self.forum, self.recup_co())
c.execute(self.text)
connection.commit()
connection.close()
sleep(5)
def recup_co(self):
self.page_html = str(urlopen(self.url_forum).read()) # stockage du contenu de la page dans une variable
self.page = BeautifulSoup(self.page_html, 'html.parser')
self.resultat = self.page.select(".nb-connect-fofo")
self.nb_co = str(self.resultat) #stockage de la ligne avec le nombre de co
self.nb_co = self.nb_co[:-27] #modification de la ligne pour ne garder que le nb de co
self.nb_co = self.nb_co[31:]
return self.nb_co
Ca fait vraiment quémandeur de code, mais je ne sais pas comment procéder
Merci d'avoir lu et de votre aide potentielle
Au passage, si vous avez des commentaires sur mon code je suis preneur de tout
Quelques remarques vite fait sur ton code :
logging
à la place des print()
pour ainsi avoir un fichier qui te donneras des informations utiles lorsque tu feras du debug.main()
dans un try / except
de sorte à savoir d'où vient l'erreur la prochaine fois (à combiner avec le logger).requests
au lieu de urllib.request
, c'est beaucoup plus user-friendly.class Forum:
suffit..split()
à la place de self.nb_co[:-27]
, pourtant quelqu'un te l'avait conseillé sur ton ancien topic. self.nb_co
, self.now
, self.text
, self.page_html
, self.page
, self.resultat
sont superflus puisqu'il vont changer très souvent, il ne décrivent pas ton forum intrinsèquement, et ils ne sont utilisés nulle part ailleurs que dans ta méthode.nb_co
en int
avant de le retourner, plutôt qu'en str
.Sinon, concernant ta question initiale, personnellement je le mettrai en dehors de la fonction recup_co
.
Ça me paraît plus logique et libre de laisser à la fonction appelante le choix de la politique :
Donc je ferais quelque chose comme ça :
while True:
try:
forum.add_to_database()
except URLError:
print("Une erreur est survenue lors de l'ouverture de l'URL.")
sleep(5)
Le 22 juin 2017 à 23:03:37 Blaff4 a écrit :
Quelques remarques vite fait sur ton code :
- Utilise un logger grâce au module
logging
à la place desprint()
pour ainsi avoir un fichier qui te donneras des informations utiles lorsque tu feras du debug.- Met ton
main()
dans untry / except
de sorte à savoir d'où vient l'erreur la prochaine fois (à combiner avec le logger).- Tu pourrais utiliser la bibliothèque
requests
au lieu deurllib.request
, c'est beaucoup plus user-friendly.- Pas besoin de parenthèses après la définition de ta classe,
class Forum:
suffit.- Tu n'as pas changé la façon dont tu récupère le code en utilisant une regex ou
.split()
à la place deself.nb_co[:-27]
, pourtant quelqu'un te l'avait conseillé sur ton ancien topic.- Tu n'as pas besoin d'assigner toutes tes fonctions à ton objet :
self.nb_co
,self.now
,self.text
,self.page_html
,self.page
,self.resultat
sont superflus puisqu'il vont changer très souvent, il ne décrivent pas ton forum intrinsèquement, et ils ne sont utilisés nulle part ailleurs que dans ta méthode.- Tu devrais convertir ton
nb_co
enint
avant de le retourner, plutôt qu'enstr
.Sinon, concernant ta question initiale, personnellement je le mettrai en dehors de la fonction
recup_co
.
Ça me paraît plus logique et libre de laisser à la fonction appelante le choix de la politique :
- Réessayer ?
- Si oui, combien de fois ?
- Attendre quelques secondes ?
- Afficher un message d'erreur ?
Donc je ferais quelque chose comme ça :
while True: try: forum.add_to_database() except URLError: print("Une erreur est survenue lors de l'ouverture de l'URL.") sleep(5)
Salut, merci de ta réponse. j'en prends compte pas de soucis Dès demain je vais mettre tout ça en œuvre
Par contre quand tu parles de faire :
while True: try: forum.add_to_database() except URLError: print("Une erreur est survenue lors de l'ouverture de l'URL.") sleep(5)
J'ai en tout 4 instances :
def main():
dixhuit_vingtcinq = Forum("dixhuit_vingtcinq", "http://www.jeuxvideo.com/forums/0-51-0-1-0-1-0-blabla-18-25-ans.htm")
moins_quinze = Forum("moins_quinze", "http://www.jeuxvideo.com/forums/0-15-0-1-0-1-0-blabla-moins-de-15-ans.htm")
quinze_dixhuit = Forum("quinze_dixhuit", "http://www.jeuxvideo.com/forums/0-50-0-1-0-1-0-blabla-15-18-ans.htm")
overwatch = Forum("overwatch", "http://www.jeuxvideo.com/forums/0-33972-0-1-0-1-0-overwatch.htm")
while(True):
dixhuit_vingtcinq.add_to_database()
moins_quinze.add_to_database()
quinze_dixhuit.add_to_database()
overwatch.add_to_database()
sleep(30)
main()
Ce qui veut dire, on est bien d'accord, qu'il faut que je mette les 4 dans le même try ?
Nope, généralement il faut mieux minimiser le code dans un try
afin d'avoir une gestion d'erreur plus fine et ainsi localiser plus précisément le problème.
En plus, si tu faisais ça et que le 18-25 était bugué alors les autres forums ne seraient jamais testés bien qu'ils puissent peut-être être accessibles, eux.
Personnellement, je regrouperai mes forums dans une liste et j'itérerai en boucle à travers afin de pouvoir tester un par un chacun d'eux.
forums = [dixhuit_vingtcinq, moins_quinze, quinze_dixhuit, overwatch]
while True:
for forum in forums:
try:
forum.add_to_database()
except URLError:
print("Une erreur est survenue lors de l'ouverture de l'URL "
"pour le forum: '{}'.".format(forum))
sleep(5)
Le 24 juin 2017 à 23:45:16 Blaff4 a écrit :
Nope, généralement il faut mieux minimiser le code dans untry
afin d'avoir une gestion d'erreur plus fine et ainsi localiser plus précisément le problème.
En plus, si tu faisais ça et que le 18-25 était bugué alors les autres forums ne seraient jamais testés bien qu'ils puissent peut-être être accessibles, eux.Personnellement, je regrouperai mes forums dans une liste et j'itérerai en boucle à travers afin de pouvoir tester un par un chacun d'eux.
forums = [dixhuit_vingtcinq, moins_quinze, quinze_dixhuit, overwatch] while True: for forum in forums: try: forum.add_to_database() except URLError: print("Une erreur est survenue lors de l'ouverture de l'URL " "pour le forum: '{}'.".format(forum)) sleep(5)
Ah ouai d'accord, c'est exactement ce qu'il me faudrait. J'espère que ca viendra avec le temps cette gestion des choses. Merci en tout cas
faire ce genre de programme sans requests
Le 25 juin 2017 à 18:41:51 Caecilius a écrit :
faire ce genre de programme sans requests
Ca fonctionnait très bien pour ce que je souhaitais faire
D'ailleurs, j'ai un souci. Depuis que je suis passé à requests j'ai un souci
Mon code
def recup_co(self):
r = requests.get(self.url_forum)
page_html = str(r.text) # stockage du contenu de la page dans une variable
page = BeautifulSoup(page_html, 'html.parser')
resultat = page.select(".nb-connect-fofo")
temp = str(resultat) #stockage de la ligne avec le nombre de co
nb_co = re.search(self.pattern, temp)
return nb_co[0]
Et j'ai l'erreur :
File "parser.py", line 59, in <module>
main()
File "parser.py", line 54, in main
forum.add_to_database()
File "parser.py", line 26, in add_to_database
text = "INSERT INTO {0}(datetime, nb_co) VALUES('{1}', '{2}')".format(self.forum, now, self.recup_co())
File "parser.py", line 43, in recup_co
return nb_co[0]
TypeError: '_sre.SRE_Match' object is not subscriptable
Je précise que j'ai cette erreur seulement sur mon serveur Debian, sur Windows ca marche niquel chrome
Merci d'avance
Ça n'a rien à voir avec Windows ou Debian.
Regarde comment s'utilise re.search()
: https://docs.python.org/3rg/3/library/re.html#re.search
C'est une fonction qui retourne soit un "match object" ( https://docs.python.org/3/library/re.html#match-objects ), soit None
si rien n'est trouvé.
Pour récupérer la valeur contenue dans ton objet, tu dois utiliser nb_co.group(0)
à la place de nb_co[0]
.
Par contre, si tu remarques un comportement différent entre Windows et Debian c'est que tu as peut-être un problème ailleurs.
Le 25 juin 2017 à 21:50:50 Blaff4 a écrit :
Ça n'a rien à voir avec Windows ou Debian.Regarde comment s'utilise
re.search()
: https://docs.python.org/3rg/3/library/re.html#re.searchC'est une fonction qui retourne soit un "match object" ( https://docs.python.org/3/library/re.html#match-objects ), soit
None
si rien n'est trouvé.Pour récupérer la valeur contenue dans ton objet, tu dois utiliser
nb_co.group(0)
à la place denb_co[0]
.Par contre, si tu remarques un comportement différent entre Windows et Debian c'est que tu as peut-être un problème ailleurs.
Ah d'accord, ca marche bien maintenant, mais je trouve ça bizarre que ca fonctionne très bien avec Windows
Merci en tout cas