Discussion utilisateur:Orlodrim/Hawk-Eye-Bot
Projet
modifierBonjour Orlodrim !
Comme tu as pu le voir hier, j'ai commencé à regarder du côté de Pywikipedia, et ça me plaît . J'en suis encore à l'apprentissage de ce nouveau langage (pour moi), mais j'aimerai me lancer dans un projet un peu plus grand. En effet, j'ai dans l'idée de mettre à jour {{Top 10 ATP actuel}} hebdomadairement à partir de ce qu'on trouve soit ici, soit là. Bon, certes, je me dis que ce n'est pas encore gagné, mais je ne désespère pas…
Tout ça pour te dire que je ne te demande pas vraiment (sauf si tu le souhaites, dans quel cas je serai d'accord forcément) de m'aider à cela, car j'imagine que tu es déjà bien débordé à droite à gauche sur Wikipedia. Cependant, saurais-tu qui pourrait m'orienter et même m'aider pour créer ce type de programme ?
J'ai pensé de mon côté à Wikialine (d · c · b) qui a créé les modèles dont les données proviennent du site de l'INSEE, un site externe.
Merci — Hawk-Eye (d) 5 avril 2013 à 08:16 (CEST)
- Bonjour,
- Pour lire un site externe, tu peux utiliser le module urllib. Ensuite, il faut que tu trouves un moyen de filtrer le contenu intéressant dans la page. Par exemple, pour lire le code et afficher les lignes qui contiennent "/Tennis/Players/Top-Players/" :
import urllib
f = urllib.urlopen("http://www.atpworldtour.com/Rankings/Singles.aspx")
code_page = f.read()
for ligne in code_page.split('\n'):
if ligne.find('/Tennis/Players/Top-Players/') != -1:
print ligne
- Extraire les données du code HTML dépend complètement de la conception de la page, c'est à faire au cas par cas (tu auras certainement besoin du modèle d'expressions régulières).
- Pour l'étape finale consistant à écrire la page, tu peux t'inspirer de Utilisateur:OrikriBot/PaS.py. Il faudrait en gros remplacer la partie qui calcule pageTemp, le nouveau code de la page.
- Orlodrim [discuter] 5 avril 2013 à 23:01 (CEST)
- Bonjour !
- J'ai regardé le code que tu m'as donné ! Merci pour l'orientation vers le module
urllib
qui a l'air très puissant, enfin en tout cas assez pour ce que je recherche à faire.- «
for ligne in code_page.split('\n'):
» veut bien dire que l'on ignore les sauts de page \n dans le code html ? - Autrement, je ne comprends pas bien la fin de la ligne «
if ligne.find('/Tennis/Players/Top-Players/') != -1:
», notamment le «!= -1
». Vraiment aucune idée de ce que ça peut vouloir signifier ! - Sinon, j'ai un peu recherché du côté du module
re
puisque je connais assez bien les expressions régulières, et voilà à quoi j'ai abouti (voir ci-dessous). Ça fonctionne, ça fait un bon tri dans le code source déjà, mais je préfère te montrer cela pour savoir si c'est bien comme ça qu'il faut agir… Pas sûr…
- «
import urllib
import re
f = urllib.urlopen("http://www.atpworldtour.com/Rankings/Singles.aspx")
code_page = f.read()
for ligne in code_page.split('\n'):
if ligne.find ('/Tennis/Players/Top-Players/') != -1:
regex_nom = re.compile ('<a href=".+?">(.+?), (.+?)</a>\s* \(([A-Z]{3})\)')
regex_points = re.compile ('<a href=".+?\?t=rb">(.+?)</a>')
nom_prenom_nation = regex_nom.findall (ligne)
points = regex_points.findall (ligne)
print nom_prenom_nation
print points
if ligne.find ('<td>') != -1:
regex_evolution = re.compile ('<td>(0|-?[0-9]{1,2})</td>')
evolution = regex_evolution.findall (ligne)
print evolution
Voilà en résumé ce que tu peux faire sur les chaînes de caractères en Python (la référence est http://docs.python.org/2/library/stdtypes.html#string-methods)
# Recherche de sous-chaîne
'abcccbd'.find('a') # la première occurrence de 'a' dans 'abcccbd' est en position 0
>>> 0
'abcccbd'.find('cc') # la première occurrence de 'cc' dans 'abcccbd' est en position 2
>>> 4
'abcccbd'.find('b', 2) # la première occurrence de 'b' dans 'abcccbd' après les deux premiers caractères est en position 5
>>> 5
'abcccbd'.find('ac') # sous-chaîne 'ac' n'existe pas dans 'abcccbd'
>>> -1
# Découpage
'abcccbd'.split('b') # découpe la chaîne en tableau en utilisant 'b' comme délimiteur.
>>> ['a', 'ccc', 'd']
# Boucle sur la chaîne découpée : affiche 'a', 'ccc' et 'd'
tableau = 'abcccbd'.split('b')
for element in tableau:
print element
# Recollage
'$'.join(tableau)
>>> 'a$ccc$d'
# Extraction d'une sous-chaîne
'abcccbd'[0]
>>> 'a'
'abcccbd'[1]
>>> 'b'
'abcccbd'[:3]
>>> 'abc'
'abcccbd'[1:3]
>>> 'bc'
'abcccbd'[-1]
>>> 'd'
'abcccbd'[-2]
>>> 'b'
'abcccbd'[-2:]
>>> 'bd'
# Longueur
len('abcccbd')
>>> 7
Cela recoupe plus ou moins ce que tu peux faire avec des regexp, à toi de choisir la méthode la plus simple selon la situation. Ça me semble bien parti. Orlodrim [discuter] 6 avril 2013 à 12:35 (CEST)
- Merci pour tout ça… Je vais revoir cela, mais un peu plus tard à tête plus reposée !!
- Autrement peux-tu m'expliquer pourquoi j'obtiens des résultats de ce type, c'est-à-dire entre crochets, voire entre crochets + parenthèses ? Et pourquoi des crochets vides quasiment un ligne sur deux ?
- Par ailleurs, je réfléchissais à l'instant qu'il ne me faut que le top 10 et pas le top 100. Il faudrait, du coup, lire le nombre présente entre les balises <span class="rank">[mon_nombre]</span> : ce doit être possible j'imagine ?
- Bonne journée — Hawk-Eye (d) 6 avril 2013 à 13:50 (CEST)
- Bonjour. J'interviens rapidement, juste pour vous signaler que j'ai fait supprimer Utilisateur:OrikriBot/PaS.py pour la raison d'une incompatibilité de licence issue d'un malentendu avec son auteur, Linedwell. Avec mes excuses, --Orikrin1998 (+) →blablatoir← 6 avril 2013 à 14:33 (CEST)
Tu as des résultats vides, parce que pour chaque joueur, il y a deux lignes qui contiennent '/Tennis/Players/Top-Players/' :
- dans la première, il n'y a que le nom (du coup 'points' est vide)
- dans la seconde, il n'y a que les points (du coup 'nom_prenom_nation' est vide).
Une technique classique pour traiter des données qui doivent arriver selon un ordre déterminer est d'utiliser un automate fini. Ici, cela consiste simplement à avoir une variable "état", que tu utilises pour te souvenir des données que tu as déjà lues. Comme elles viennent toujours dans le même ordre, tu peux utiliser "état" pour savoir quoi faire ensuite.
Voilà ce que ça peut donner. Je n'ai pas mis la lecture du champ "évolution". J'utilise le fait que dans le code de la page, chaque ligne du tableau commence par un '<td class="first">'.
code_page = f.read()
PAS_DANS_UNE_LIGNE = 0
DEBUT_LIGNE = 1
RANG_LU = 2
NOM_LU = 3
POINTS_LU = 4
# Compile toutes les regexp une seule fois au début, c'est plus efficace
regex_rank = re.compile('<span class="rank">([0-9]+)')
regex_nom = re.compile('<a href=".+?">(.+?), (.+?)</a>\s* \(([A-Z]{3})\)')
regex_points = re.compile ('<a href=".+?\?t=rb">(.+?)</a>')
etat = PAS_DANS_UNE_LIGNE
for ligne in code_page.split('\n'):
if ligne.strip() == '<td class="first">':
etat = DEBUT_LIGNE
elif etat == DEBUT_LIGNE:
rang = regex_rank.findall(ligne)
etat = RANG_LU
elif etat == RANG_LU:
nom_prenom_nation = regex_nom.findall(ligne)
# Ne passe dans l'état suivant que si la regexp est trouvée (cela permet d'ignorer les lignes vides)
if nom_prenom_nation:
etat = NOM_LU
elif etat == NOM_LU:
points = regex_points.findall(ligne)
if points:
# Si on arrive ici, c'est qu'on a réussi à lire le rang, nom_prenom_nation et les points
print "rang=", rang
print "nom_prenom_nation=", nom_prenom_nation
print "points=", points
etat = PAS_DANS_UNE_LIGNE
Orlodrim [discuter] 6 avril 2013 à 15:47 (CEST)
Bonsoir Orlodrim !
Meilleures nouvelles aujourd'hui, cette fois-ci, c'est beaucoup mieux. J'ai (re)vu tout ce qui concerne les listes, et voilà à ce quoi j'arrive (fier de moi ^^, enfin surtout comparé à hier soir ).
... # Rien n'a changé avant cela
etat = PAS_DANS_UNE_LIGNE
for ligne in code_page.split('\n'):
if ligne.strip() == '<td class="first">':
etat = DEBUT_LIGNE
elif etat == DEBUT_LIGNE:
listerang = regex_rank.findall(ligne)
etat = RANG_LU
elif etat == RANG_LU:
nom_prenom_nation = regex_nom.findall(ligne)
# Ne passe dans l'état suivant que si la regexp est trouvée (cela permet d'ignorer les lignes vides)
if nom_prenom_nation:
etat = NOM_LU
elif etat == NOM_LU:
listepoints = regex_points.findall(ligne)
if listepoints:
# Si on arrive ici, c'est qu'on a réussi à lire le rang, nom_prenom_nation et les points
tuple_intermediaire = nom_prenom_nation[0]
rang = listerang[0]
points = listepoints[0]
nom, prenom, nation = tuple_intermediaire
rang = int(rang)
while rang < 11 : # Sélection du Top 10 uniquement
rang = str(rang) # Sinon message d'erreur car Python ne peut concaténer les classes str + int ensemble
print '! scope="row" | ' + rang + '\n| align="left" | ' + '{{' + nation + '-d}}' + ' ' + '[[' + prenom + ' ' + nom + ']]' \
+ '\n| align="right" | {{formatnum:' + points + '}}\n'
etat = PAS_DANS_UNE_LIGNE
Voilà, donc y a du mieux hein ? (Rassure-moi, please !)
Il me reste encore quelques soucis bien sûr… Le premier reste l'insertion du champ "évolution" dans le mécanisme de l'automate fini. J'ai essayé de mon côté mais sans succès (je m'y perd avec ses elif : je me repencherai sur ça peut-être demain). Bonne soirée — Hawk-Eye (d) 7 avril 2013 à 21:27 (CEST)
- Ça avance, je vois .
- Plutôt que "while rang < 11", tu devrais mettre un "if rang < 11" (tu ne veux exécuter qu'une fois au plus ce qu'il y a dans le bloc, si rang < 11).
- Pour afficher des nombres, tu peux utiliser une chaînes de format avec les valeurs ensuite. Par exemple :
print u'nombre=%i, chaîne=%s, nombre=%i, chaîne=%s' % (123, u'Abc', 456, u'Def')
- affichera "nombre=123, chaîne=Abc, nombre=456, chaîne=Def".
- Pour l'évolution, il faudra rajouter un état (en fait il y est déjà : POINTS_LU) et un "elif". Redemande-moi si tu as un problème.
- Orlodrim [discuter] 7 avril 2013 à 21:45 (CEST)
- pour le while.
- A la place de ce que tu proposes, on peux aussi utiliser (j'ai lu ça il y a deux jours, et ce que tu m'as dit me la fait souvenir, alors autant l'appliquer). Tu confirmes ?
if rang < 11 :
print '! scope="row" | {0} \n| align="left" | {{{1}-d}} [[{2} {3}]]\n| align="right" | {{formatnum:{4}}}\n'.format(rang, nation, prenom, nom, points)
- Le seul problème résidant dans le que la surabondance de {{ embrouille un peu le résultat. J'ai essayé d'échapper avec « \{\{ » mais sans succès.
- Autrement, voilà ce que j'avais fait pour le rajout d'état « évolution » (j'ai mis les deux lignes avant et après pour que tu puisses t'y retrouver par rapport au code précédemment cité) :
if listepoints: #### cette ligne était présente
etat = POINTS_LU
elif etat == POINTS_LU:
listeevolution = regex_evolution.findall(ligne)
if listeevolution:
# Si on arrive ici, c'est qu'on a réussi à lire le rang, nom_prenom_nation, les points et l'évolution // NORMALEMENT ^^
tuple_intermediaire = nom_prenom_nation[0] #### cette ligne était présente
- Il ne semble pas y avoir d'erreur (aucune n'est affichée dans la console), et ça m'a même l'air de fonctionner ^^ ! — Hawk-Eye (d) 7 avril 2013 à 22:43 (CEST)
Bonsoir !
Je reviens un peu à la charge, plusieurs « problèmes » me viennent à la tête. Mais chaque chose en son temps, je commence par ce qui est peut-être le principal : quand le programme se lance dans l'invite de commande, pas de soucis, les infos « défilent » les unes sous les autres. On est content, donc ; enfin JE suis content . Cependant, le fait de mettre ces informations dans un fichier texte annexe (c'est en s'entraînant qu'on apprend, hein !), je me rend compte que l'on a seulement les données concernant le 10e mondial, c'est-à-dire les derniers. En fait, à chaque passage, les données sont écrasées, et on se retrouve seulement avec les dernières (cela n'était pas perceptible via la console). Tu vois le problème que je soulève ?
Si oui, y a-t-il une astuce bien connue des « adeptes » de Python pour remédier à ce problème, car de mon côté — et ce n'est pas faute d'avoir cherché — je ne vois pas bien comment capturer l'ensemble des données.
— Hawk-Eye (d) 8 avril 2013 à 21:58 (CEST)
- Bonsoir,
- Ma boule de cristal me dit que tu écris dans le fichier comme ça :
for ligne in code_page.split('\n'):
...
with open('machin.txt', 'w') as f:
f.write('blabla')
- (si c'est pas ça, donne-moi ton code source !)
- Chaque appel à 'open' efface le fichier. La solution la plus simple est d'imbriquer la boucle 'for ...' dans le bloc 'with open...' plutôt que l'inverse :
with open('machin.txt', 'w') as f:
for ligne in code_page.split('\n'):
...
f.write('blabla')
- Tu peux aussi stocker le code dans une liste, puis écrire le fichier d'un seul coup à la fin :
code_modele = []
for ligne in code_page.split('\n'):
...
code_modele.append('blabla')
with open('machin.txt', 'w') as f:
f.write('\n'.join(code_modele))
- Si ton objectif ultime est d'écrire le résultat sur une page wiki et pas dans un fichier, tu as plutôt intérêt à utiliser la seconde solution.
- Orlodrim [discuter] 9 avril 2013 à 23:59 (CEST)
Salut !
Trop forte ta boule de cristal, j'veux la même !
Je m'en veux tellement de ne pas avoir pensé à la 1re des deux solutions tout seul, horrible ! Mais finalement, j'ai bien fait de te demander car j'ai opté pour le 2de, comme tu me le suggérais. Merci bien pour ce coup de pouce (= ).
Comme tu peux le constater, je pense avoir fini mon programme (au passage, j'ai résolu plusieurs questions que je voulais te poser tout seul « comme un grand », hihi). Mais il me reste quelques autres questions, la plus prioritaire – car je me la pose depuis plusieurs jours déjà (pas plus d'une semaine quand même, je n'y connaissais rien !) – étant la première :
- Si on veut intervenir sur une liste de page (inclusions) contenant le modèle {{Exemple}} (je ne veux pas intervenir dessus, mais c'est juste pour … l'exemple !), comment doit-on travailler ? À partir d'une liste de fichier préalablement écrite sur un
*.txt
? Y a-t-il une quelconque fonction de Pywikipedia permettant de l'obtenir directement ? Car moi, je travaille sur mon*.py
et change à chaque fois manuellement le nom de la page dans mon fichier :page = wikipedia.Page(site, u'Article_1')
→page = wikipedia.Page(site, u'Article_2')
- Qui découle de cette première question : ce serait bien du coup, que la console indique le nom de la page qu'elle traite (pas trop dur) et qu'elle demande si on travaille dessus, si on la passe (un peu à la manière de
redirect.py
). Mais pour ça, il faut d'abord que j'ai la réponse à la première question)
- Qui découle de cette première question : ce serait bien du coup, que la console indique le nom de la page qu'elle traite (pas trop dur) et qu'elle demande si on travaille dessus, si on la passe (un peu à la manière de
- Ma deuxième question concerne la régularité du programme (je viens d'être « accepté » sur Labs me semble-t-il). Lorsque l'on veut rendre un programme régulier dans le temps (une fois le lundi à 5 h par exemple), comment ça se passe ? Est-ce à partir du module
time
, directement dans le code ? Ou bien est autre chose (un fichier annexe) ? J'ai besoin de bien des éclaircissements à ce propos, car je n'ai rien trouvé à droite à gauche.
Voilà, bien sûr, si tu as des exemples à me donner (sur des scripts qui sont en libre accès sur wiki/web) plutôt qu'une réponse qui te prends du temps, tu peux me donner les liens, j'en serai déjà ravis !
Dernière petite question subsidiaire : est-ce que l'emploi de « while i < X
» avec incrémentation de 1 à i pour chaque tour de boucle augmente considérablement le temps d'exécution d'un script ? Car dans un autre programme que je viens de créer (qui ne contient aucune boucle « while
») et que je teste actuellement, le script est très rapide. Comparé à celui de mise à jour du modèle {{Top 10 ATP actuel}} qui utilise un while i < 2
(0 étant l'état « simple » et 1 l'état « double »), et depuis j'ai comme l'impression qu'il s'est largement ralenti !
Peut-être que tu voudrais voir le code d'ailleurs ?
Bonne soirée — Hawk-Eye (d) 11 avril 2013 à 00:21 (CEST)
Bonjour,
(question 1) La liste des inclusions s'obtient avec la fonction getReferences, par exemple :
site = pywikibot.getSite()
modele = pywikibot.Page(site, u'Modèle:Exemple')
for page in modele.getReferences(onlyTemplateInclusion=True):
print page.title()
(question 2) Si tu veux lancer ton programme toutes les cinq heures, utilise cron. Ce n'est pas une fonction python, c'est un démon qui existe sur tous les systèmes de type Unix, et qui sert à lancer d'autres programmes à intervalle régulier. Il se configure avec la commande crontab. Par exemple, pour lancer un programme toutes les 2 heures (et à la minute 18), tu tapes "crontab -e" et tu ajoutes une ligne dans le fichier de la forme :
18 */2 * * * /chemin/de/ton/programme.py
Faire tourner le programme python en permanence et mettre une fonction d'attente est possible, mais cela gaspille les ressources du serveur comparé à cron.
(question 3) Le temps d'exécution d'un while est la somme du temps d'évaluation de la condition (négligeable s'il s'agit d'une comparaison) plus le temps d'exécution de ce qu'il y a à l'intérieur, autant de fois que c'est répété. Écrire :
i = 0
while i < 3:
print i
i += 1
prendra exactement le même temps que :
i = 0
print i
i += 1
print i
i += 1
print i
i += 1
(note en passant, c'est équivalent à :
for i in xrange(3):
print i
)
La lenteur peut venir du temps qu'il faut pour les les pages web. Sinon, je ne peux pas deviner.
Orlodrim [discuter] 12 avril 2013 à 19:14 (CEST)
- Bonjour Orlodrim.
- Question 1 : ! Merci, il n'y avait pas cette explication sur Aide:Pywikipedia/manuelFR, du coup, j'étais coincé pour le «
onlyTemplateInclusion=True
». - Question 2 : Hum, encore quelque chose de nouveau pour moi… Si je comprend bien, c'est un fichier externe qui lance le programme.py à l'heure et selon la fréquence indiquée ? Cette technique est valable si on laisse l'ordi ouvert 24h/24, ou bien l'est-elle aussi quand on met le programme sur le serveur ?
- Je ne comprend pas bien ce que veulent dire les astérisques dans la ligne de commande ?
- (J'ai ouvert un compte sur Wikimedia Labs il y a peu, et je suis « accepté » dans le « Bots project ». Après, je ne m'en sors pas, je ne sais pas comment faire pour déposer les scripts. Comme je ne t'ai pas vu inscrit là-bas, je ne pense pas que tu puisse m'aider alors j'ai demandé un peu d'aide à ce propos à Quentinv57 (d · c).)
- Bon dimanche — Hawk-Eye (d) 14 avril 2013 à 10:00 (CEST)
- cron est un programme qui tourne en permanence en arrière-plan sur les systèmes Unix/Linux, pourvu que l'ordinateur soit en marche, et dont la seule fonction est de lancer les programmes listés dans ses fichiers de configuration (un par compte sur la machine). Le '*' veut dire "sans contrainte sur cette colonne" (explications : Crontab#Notation). Je ne sais pas s'il tourne sur ton ordinateur (ça dépend de ton système d'exploitation), mais il tourne certainement sur le serveur auquel tu as accès, qui fonctionne en permanence.
- La procédure pour accéder aux serveurs semble être décrite sur Wikitech:Help:Access. Effectivement je n'ai pas de compte sur Wikimedia Labs, donc je ne pourrai pas te guider plus en détail.
- Orlodrim [discuter] 14 avril 2013 à 10:29 (CEST)
- Je suis sur Windows 8, donc je ne dois pas avoir accès à cron. Il va falloir que je me débrouille pour avoir accès aux serveurs de WikiLabs, alors. Je te tiens au courant ! — Hawk-Eye (d) 14 avril 2013 à 10:47 (CEST)
Quelques nouvelles
modifierBonjour Orlodrim !
Quelques nouvelles à propos de la mise sur le serveur de certains scripts d'Hawk-Eye-Bot (d · c) : je n'ai finalement pas réussi, malgré de nombreux essais. Alors, je laisse un peu ça de côté pour le moment, ça m'a lassé !
Sinon, le script où tu m'avais largement aidé fonctionne à merveille (voir {{Top 10 ATP actuel}}), et j'en ai fait un autre parallèlement qui fonctionne aussi bien pour mettre à jour les infobox des joueurs de tennis hebdomadairement.
Mais j'ai une petite question qui me trotte dans la tête :
Dans AWB, il y avait une possibilité de travailler uniquement dans un modèle précis. Par exemple, si j'ai besoin de travailler sur le paramètre légende d'un {{modèle-1}}, et que je ne veux pas modifier le {{modèle-2}} qui contient aussi un paramètre légende, alors je le précisais au sein du logiciel sus-cité. Avec Python, tu aurais un « tuyau » à me donner pour parvenir à la même chose assez simplement ? J'imagine bien que c'est possible mais je ne vois pas trop comment, en fait… Mais cela ne presse pas vraiment, c'est juste pour info, quand j'essaierai de résoudre des requêtes aux bots avec pywikipedia dans le futur, pour ne pas faire de bêtises en somme…
Arf, et puis j'en ai une autre, en fait ! Elle concerne ce que tu peux voir sur la page « Utilisateur:Hawk-Eye/Brouillon/4 ». Je cherche (désespérément) à remplacer les {{INC-d}} par le drapeau correspondant avec les données qui sont présentes au 1er tour. Par exemple, j'aimerai que David Ferrer se retrouve avec {{ESP-d}} à partir dès 1/8 de finale, et cela pour tous les joueurs à tous les tours. J'ai tenté de passer par les expressions régulières, pas de choix je pense, mais je m'embrouille et je pense que je cherche trop compliqué ! Tu pourrais me donner une piste, si tu vois comment régler cela ?
À bientôt & merci — Hawk-Eye (d) 7 mai 2013 à 20:00 (CEST)
Bonjour,
Pour remplacer dans un modèle, tu peux d'abord créer une regexp pour extraire le modèle qui t'intéresse et son contenu. Ensuite, tu appeles re.sub avec comme deuxième paramètre une fonction qui fait le remplacement à l'intérieur du modèle. Voilà une version minimale qui ignore les modèles contenant des modèles imbriqués (sinon créer la regexp devient assez compliqué, et les modèles imbriqués peuvent avoir des paramètres du même nom que le modèle principal). Dis-moi si tu as besoin d'aide pour gérer les cas plus complexes.
def remplace_simple(match):
texte = match.group(0)
# Cette fonction reçoit uniquement le texte à l'intérieur du modèle traité.
# C'est ici qu'il faut implémenter le remplacement proprement dit.
print u'Fonction remplace_simple appelée sur "%s"' % texte
if '<nowiki>' in texte:
# <nowiki> peut être problématique, cf. deuxième exemple (pour être fiable,
# il faudrait aussi vérifier d'autres balises commes </nowiki>, <pre>,
# <math>, <syntaxhighlight lang="text">, etc., et les commentaires).
print u'Cas à traiter à la main...'
return texte
return texte.replace('|foo=', '|bar=')
def remplace_dans_modele(texte):
# Trouve les occurrences d'un modèle donné et appelle remplace_simple pour chacune.
# Exemple pour "Lien web"
return re.sub(r'\{\{(\s|_)*[Ll]ien(\s|_)+web(\s|_)*\|[^{}]*\}\}', remplace_simple, texte)
print remplace_dans_modele(u'{{Lien web|foo=3}} {{Lien web truc|foo=4}} {{lien_web|foo=5}} abc')
print remplace_dans_modele(u'{{Lien web|bar=<nowiki>}}</nowiki>|foo=4}}')
Pour le (2) : tu peux faire une première boucle ligne par ligne pour lire les drapeaux connus dans un dictionnaire, puis une seconde pour remplacer ceux qui manquent.
def propagation_drapeaux(texte):
drapeau_par_joueur = {}
for ligne in texte.split('\n'):
drapeau_par_joueur = {}
#<si la ligne contient un drapeau et un joueur>
if drapeau != 'INC-d':
drapeau_par_joueur[joueur] = drapeau
for ligne in texte.split('\n'):
#<si la ligne contient un drapeau et un joueur>
if drapeau == 'INC-d' and joueur in drapeau_par_joueur:
#<remplacer le drapeau par drapeau_par_joueur[joueur] dans ligne>
#<concaténer toutes les lignes>
Orlodrim [discuter] 8 mai 2013 à 01:02 (CEST)
- Pour la première question, je n'ai pas encore eu l'occasion de pouvoir tester cela.
- Par contre, pour la deuxième, c'est parfait . J'ai un peu adapté à ma sauce, et ça marche parfaitement !
- Je suis désormais face à un problème d'un autre type. J'ai un peu « bidouillé » avec les mises à jours de pywikipedia, et me voilà avec un message d'erreur dès lors que je lance un script que j'ai écrit (alors que ceux comme par exemple replace.py que je n'ai pas écrit fonctionnent très bien). Je te laisse admirer ça ! [1]. Ce qui pose problème est cela apparemment :
>>>from pywikibot.support import *
ImportError: No module named support
- Je vois vraiment pas pourquoi ça se met à délirer… Bon, en attendant, je vais arrêter mes expériences. — Hawk-Eye (d) 14 mai 2013 à 12:11 (CEST)
- J'avoue que je ne vois pas trop... essaye de mettre ton programme dans le même dossier que replace.py au lieu d'un sous-dossier "script", peut-être. Orlodrim [discuter] 15 mai 2013 à 23:01 (CEST)
- Arfff . Je vais retenter quelque chose demain alors ! Merci pour le conseil — Hawk-Eye (d) 15 mai 2013 à 23:16 (CEST)
- Bon, ben … … … T'avais ENCORE raison ! Je ne vois pas trop pourquoi ça me donnait cette erreur du coup ! Mais en mettant mes scripts dans le répertoire de pywikipedia, impeccable . Merci !!! —Hawk-Eye (d) 16 mai 2013 à 08:21 (CEST)
- Pour info, je mettais mes scripts dans un dossiers scripts qui était placé à l'intérieur du répertoire pywikipedia. Voilà comment donc j'introduisais mes scripts, par exemple :
- J'avoue que je ne vois pas trop... essaye de mettre ton programme dans le même dossier que replace.py au lieu d'un sous-dossier "script", peut-être. Orlodrim [discuter] 15 mai 2013 à 23:01 (CEST)
import re
import urllib
import sys
sys.path.append('C:/Users/''myname''/Documents/pywikipedia') # J'ajoute cela car par défaut il cherche dans le dossier local 'C:/Users/''myname''/Documents/pywikipedia/scripts'
import wikipedia
- Tu vois ce qui pourrait clocher, toi, là-dedans ? Je ne vois pourtant pas d'horreur … — Hawk-Eye (d) 16 mai 2013 à 08:41 (CEST)
- Est-ce qu'il y a une copie de wikipedia.py dans le dossier scripts ? Si oui, supprime-la. Est-ce que ça marche en remplaçant "sys.path.append('C:/..." par "sys.path.insert(1, 'C:/..." ? Si oui, tu as probablement plusieurs copies de pywikipedia installées. Orlodrim [discuter] 16 mai 2013 à 21:12 (CEST)
- Tu vois ce qui pourrait clocher, toi, là-dedans ? Je ne vois pourtant pas d'horreur … — Hawk-Eye (d) 16 mai 2013 à 08:41 (CEST)
Mais je vais encore avoir besoin de ton expérience. J'ai besoin de mettre à jour la version de pywikipedia avec ça. Je m'y prend comment, en gros ? (j'ai téléchargé TortoiseSVN pour Windows). Je préfère te demander, car en essayant tout seul, j'ai essuyé le problème ci-dessus, que tu m'as résolu. — Hawk-Eye (d) 16 mai 2013 à 08:25 (CEST)
- Je ne connais pas TortoiseSVN. Suivre les instructions de cette page de manuel devrait marcher. Orlodrim [discuter] 16 mai 2013 à 21:12 (CEST)