def supprimer(self, page): """ Supprime la page et nettoie les pages liées """ t = page.title().encode('ascii', 'ignore') titres = [ t ] titres.append(t.replace('Discussion:', 'Discuter:')) for b in page.backlinks(filterRedirects=True): # On trouve les différents noms de la page t = b.title().encode('ascii', 'ignore') titres.append(t) titres.append(t.replace('Discussion:', 'Discuter:')) # PdDis disc = pywikibot.Page(self.site, page.title().replace('/Traduction', '')) if disc.exists(): # Nettoyage de PdDis self.suppr_mod(disc, titres) for b in page.embeddedin(): # nettoyage des inclusions self.suppr_mod(b, titres) for b in page.backlinks(followRedirects=True): # Nettoyage des redirections if b.isRedirectPage(): BeBot.delete(b, self.resume+" : Redirection d'une traduction abandonnée", debug=self.debug) self.stats['suppr'] += 1 #taille = BeBot.taille_page(page, 1) # < 2800 #taille = 7777 taille = 0 m = self.re_discus.search(page.text) if m: taille = len(m.group(1)) if taille < 260: BeBot.delete(page, self.resume+' : Traduction abandonnée', debug=self.debug) self.stats['suppr'] += 1 else: pywikibot.output("><> Discussion détectée sur : http://fr.wikipedia.org/wiki/%s -- taille:%d" % (page.title(), taille)) self.gros_suivi.append(page.title())
def lycos(self, nom_base, conditions=None, limite=None): """ Récupère les articles labellisés de la base correspondants à certaines conditions """ rep = {} champs = [ 'page', 'taille', 'traduction', 'label' ] articles = BeBot.charger_bdd(self.db, nom_base, \ champs=", ".join(champs), cond=conditions) #articles = sorted(articles.items()) i = 0 for a in articles: if limite is not None and i >= limite: break i += 1 page = {} nom_page = unicode(a[0], 'UTF-8') page[champs[1]] = int(a[1]) if a[2] is not None: page[champs[2]] = unicode(a[2], 'UTF-8') else: page[champs[2]] = None page[champs[3]] = unicode(a[3], 'UTF-8') page['avancement'] = BeBot.info_wikiprojet( \ pywikibot.Page(self.site_fr, nom_page), \ self.avancementER, 'avancement', \ self.retrait_avancement) rep[nom_page] = page return rep
def run(self): adq_wp = [] adq_base = [] res = BeBot.charger_bdd(self.conn, self.nom_base, ordre='"titre" ASC') for r in res: adq_base.append(pywikibot.Page(self.site, r['titre'])) for cat in self.cats: labels = pywikibot.Category(self.site, cat) for a in labels.articles(): adq_wp.append(a) # Différences nouveaux = list(set(adq_wp) - set(adq_base)) dechus = list(set(adq_base) - set(adq_wp)) for a in nouveaux: self.ajouteralabdd(a) for a in dechus: self.supprimerdelabdd(a) if len(dechus) > 0: pywikibot.output("Articles déchus de leur status : {0}".format(dechus)) # Génération du flux res = BeBot.charger_bdd(self.conn, self.nom_base, lim=50, ordre='"date" DESC') for r in res: p = pywikibot.Page(self.site, r['titre']) date = datetime.datetime.strptime(r['date'], '%Y-%m-%d %H:%M:%S') categorie = r['label'] self.ajouterauflux(p, date, categorie) if not self.debug: #self.feed.write(self.fp, 'utf-8') self.fp.write(self.feed.to_string()) pywikibot.output("Nombre de modifications sur la base : {0}".format(self.conn.total_changes)) self.fp.close()
def adl(self, mag): """ (Avec le wikimag) Ajoute les adq/ba de la semaine à l'Atelier de Lecture """ separation = '<center><hr style="width:42%;" /></center>' split = re.compile("\|([\w \xe9]+?)=", re.LOCALE|re.UNICODE|re.MULTILINE|re.DOTALL) lien = re.compile("\[\[.*?\]\]", re.LOCALE|re.UNICODE) params = { 'adq': '', 'propositions adq' : '', 'ba' : '', 'propositions ba' : '' } # Les paramètres du mag a = re.split(split, mag.text) for i in range(1, len(a), 2): #retrait des liens a[i] = lien.sub(r'', a[i]) params[a[i].lower()] = a[i+1].rstrip('\n').strip(' ') lumiere = pywikibot.Page(self.site, 'Wikipédia:Atelier de lecture/Lumière sur...') #Retrait des a-label alabel = re.compile("\{\{[aA]-label\|([^\}\|]+).*?\}\}", re.LOCALE|re.UNICODE) params['adq'] = alabel.sub(r'[[\1]]', params['adq']) params['propositions adq'] = alabel.sub(r'[[\1]]', params['propositions adq']) params['ba'] = alabel.sub(r'[[\1]]', params['ba']) params['propositions ba'] = alabel.sub(r'[[\1]]', params['propositions ba']) propositions = params['propositions adq'] + '\n' + params['propositions ba'] #Ajout des icones icone = re.compile("^\* ", re.LOCALE|re.UNICODE|re.MULTILINE) params['adq'] = icone.sub(r'* {{AdQ|20px}} ', params['adq']) params['ba'] = icone.sub(r'* {{BA|20px}} ', params['ba']) lumiere.text = '[[Fichier:HSutvald2.svg|left|60px]]\nLes articles labellisés durant la semaine dernière et les nouvelles propositions au label.{{Clr}}\n' \ + '\n{{colonnes|nombre=3|\n' + params['adq'] + '\n}}\n' + separation \ + '\n{{colonnes|nombre=3|\n' + params['ba'] + '\n}}\n' + separation \ + '\n{{colonnes|nombre=3|\n' + propositions + '\n}}\n' \ + '<noinclude>\n[[Catégorie:Wikipédia:Atelier de lecture|Lumière sur...]]\n</noinclude>' pywikibot.output("# Publication sur l'Atelier de lecture") BeBot.save(lumiere, commentaire='Maj hebdomadaire de la liste', debug=self.debug)
def run(self): self.label_se = self.lycos(self.nom_base, \ conditions="traduction IS NULL", limite=self.limite_label_se) art_etrangers = self.lycos(self.nom_base, conditions="traduction IS NOT NULL") art_fr = self.lycos('contenu_de_qualite_fr') for page_et, infos_et in art_etrangers.items(): eq_fr = infos_et['traduction'] if art_fr.has_key(eq_fr): self.label_deux[page_et] = infos_et else: page_trad = BeBot.togglePageTrad(pywikibot.Page(self.site_fr, eq_fr)) if page_trad.exists(): self.label_trad[page_et] = infos_et self.label_trad[page_et]['souspage_trad'] = page_trad ipt = self.infos_page_suivi(page_trad) self.label_trad[page_et]['statut'] = ipt['statut'] self.label_trad[page_et]['progression'] = ipt['progression'] else: self.label_nofr[page_et] = infos_et self.label_nofr[page_et]['taille_fr'] = BeBot.taille_page( \ pywikibot.Page(self.site_fr, eq_fr)) self.total = len(self.label_se) + len(self.label_nofr) \ + len(self.label_deux) + len(self.label_trad)
def publier(self, souspage, liste, soustableau=0, simple=False): """ Raccourci pour publier une liste d'article sur une souspage du P:SAdQaW La paramètre « simple » permet d'obtenir un affichage simplifié sous forme d'une liste de liens. """ retour = u'%s pages.\n\n' % str(len(liste[soustableau])) if simple: m = [] for t in liste[soustableau]: m.append(t.title()) retour += u'<noinclude>[[' + u']], [['.join(m) + u']].\n</noinclude>\n' else: noinclude = False for i, t in enumerate(liste[soustableau]): retour += u'{{%s}}' % t.title() if i == 11: retour += u'<noinclude>' noinclude = True retour += u'\n' if noinclude: retour += u'</noinclude>' #pywikibot.Page(self.site, u'Projet:Suivi des articles de qualité des autres wikipédias/Traduction/' + souspage).put(retour, comment=self.resumeListing) p = pywikibot.Page(self.site, u'Projet:Suivi des articles de qualité des autres wikipédias/Traduction/' + souspage) p.text = retour BeBot.save(p, commentaire=self.resumeListing)
def run(self): ################################## ##### Candidatures cats = [ pywikibot.Page(self.site, u"Modèle:Lien AdQ"), pywikibot.Page(self.site, u"Modèle:Lien BA") ] for c in cats: for m in c.backlinks(namespaces=0): if m.title() not in self.ignor_list: # ... alors prendre la page de trad tradpage = BeBot.togglePageTrad(m) for t in self.traductions: if t.title() == tradpage.title(): #Vérification de la correspondance des langues cibles cibleTrad = self.langueCible(tradpage)[0] for cible in self.langueCible(m): if cibleTrad == cible: self.candidats.append([tradpage, cibleTrad]) break; break; ################################## ##### Mise à jour du suivi for tq in self.tradQualite: #Tri par statut statut = 0 for cat in tq.categories(): # pywikibot.output(cat.title()) if cat.title() == u"Catégorie:Article à traduire": #1 statut = 1 break elif cat.title() == u"Catégorie:Article en cours de traduction": #2 statut = 2 break elif cat.title() == u"Catégorie:Article à relire": #3 statut = 3 break elif cat.title() == u"Catégorie:Article en cours de relecture": #4 statut = 4 break elif cat.title() == u"Catégorie:Traduction terminée": #5 statut = 5 break self.trads[statut].append(tq) ### Publication des listings self.publier(u'DemandeTraduction', self.trads, 1) self.publier(u'EnTraduction', self.trads, 2) self.publier(u'DemandeRelecture', self.trads, 3) self.publier(u'EnRelecture', self.trads, 4) # Cas de statut 5 (terminé) for pt in self.trads[5]: etat_label = 0 for cat in BeBot.togglePageTrad(pt).categories(): if cat.title() == u"Catégorie:Article de qualité" or cat.title() == u'Catégorie:Bon article' : etat_label = 2 break self.term_et_label[etat_label].append(pt) self.publier(u'Labellisées', self.term_et_label, 2, True) #pywikibot.Page(self.site, u"Projet:Suivi des articles de qualité des autres wikipédias/Traduction/En attente d'être labellisées").put(self.genererListing(self.term_et_label[1]), comment=self.resumeListing) self.publier(u'Terminées sans label', self.term_et_label, 0, False)
def run(self): for a in [2007, 2008, 2009, 2010, 2011]: for s in range(1,53): p = pywikibot.Page(self.site, u'Wikipédia:Wikimag/%d/%d' % (a, s)) if p.exists() and not p.isRedirectPage(): #pywikibot.output(p.title()) p.text += self.categorie BeBot.save(p, commentaire=self.resume, minor=True)
def newsboy(self, lecteur, msg, purge=True): """ Distribut l'infolettre """ if lecteur.isRedirectPage(): lecteur = lecteur.getRedirectTarget() if purge: self.rm_old(lecteur) lecteur.text += msg BeBot.save(lecteur, commentaire=self.resume, debug=self.debug)
def clore_traduction(self, page): """ Clôt une traduction """ #pywikibot.output("&&& clore : %s" % page.title()) page.text = self.re_statut.sub('|status=5', page.text) com = self.resume BeBot.save(page, commentaire=com, debug=self.debug) self.retirer_le_modele_Traduction(BeBot.togglePageTrad(page)) self.stats['cloture'] += 1
def retirer_le_modele_Traduction(self, page): """ Retire le {{Traduction}} d'une page """ ns = page.namespace() if ns == 2 or ns == 3: pywikibot.output('Page utilisateur %d (retirer_modele) -> exit : %s' % (ns, b.title())) return text = self.re_trad.sub(r'', page.text) if text != page.text: page.text = text BeBot.save(page, commentaire=self.resume+' : Retrait du modèle {{Traduction}}', minor=True, debug=self.debug)
def main(): site = pywikibot.getSite() if BeBot.blocage(site): sys.exit(7) log = u'Utilisateur:BeBot/Traduction de qualité' tdq = TraductionDeQualite(site, log) tdq.run() p = pywikibot.Page(site, log) p.text = unicode(tdq) BeBot.save(p, commentaire=tdq.resume)
def suppr_mod(self, b, titres): ns = b.namespace() if ns == 2 or ns == 3: #pywikibot.output('Page utilisateur %d (suppr_mod) -> exit : %s' % (ns, b.title())) return self.retirer_le_modele_Traduction(b) # si traduction active for a in re.finditer(self.re_appel, b.text): trouve = a.group(1).encode('ascii', 'ignore') if trouve in titres: c = b.text[:a.start()] + b.text[a.end():] #BeBot.diff(b.text, c) b.text = c BeBot.save(b, commentaire=self.resume+' : Traduction abandonnée', debug=self.debug)
def run(self): if self.infolettre == "wikimag": msg = self.wikimag() elif self.infolettre == "raw": msg = self.raw() else: pywikibot.output("Infolettre '%s' inconnue. Abandon." % self.infolettre) sys.exit(1) # Liste des abonnés r = re.compile("\*\* \{\{u\|(.+?)\}\}\s*(\{\{BeBot nopurge\}\})?", re.LOCALE|re.UNICODE|re.IGNORECASE) liste = [] # [ Nom d'utilisateur ; bool : purge des anciens ] for i in BeBot.page_ligne_par_ligne(self.site, self.abn[self.infolettre]): m = r.search(i) if m is not None: purge = True if m.group(2) is not None: purge = False liste.append([m.group(1), purge]) # Distribution if hasattr(self, "resume"): for l,p in liste: boiteauxlettres = pywikibot.Page(self.site, "Utilisateur:"+l).toggleTalkPage() self.newsboy(boiteauxlettres, msg, p)
def main(): if BeBot.blocage(pywikibot.getSite()): sys.exit(7) try: opts, args = getopt.getopt(sys.argv[1:], "s") except getopt.GetoptError, err: print str(err) usage() sys.exit(2)
def put_resultats(self): """ Affichage des résultats """ total = self.resultats['nb_pages'] msg = '== Statistiques ==\nAu %s\n' % datetime.datetime.today().strftime("%d/%m/%Y") msg += "* Nombre total de pages : %i\n" % total msg += "* Par statut:\n" for c, nbpages in self.paravancement.items(): msg += "** %s : %i\n" % (c, nbpages) cat = pywikibot.Category(self.site, "Catégorie:Projet:Traduction/Articles liés") msg += "* Pages de suivi actives : %i\n" % len(list(cat.articles())) msg += "\n[[Catégorie:Maintenance du Projet Traduction|*]]\n" res = pywikibot.Page(self.site, "Projet:Traduction/Statistiques") stats = re.compile("^== Statistiques ==[^=]*", re.DOTALL|re.MULTILINE) res.text = stats.sub(r'', res.text) res.text = res.text + msg BeBot.save(res, commentaire=self.resume)
def ajouteralabdd(self, page): # Suppression d'un modèle chiant pour le calcul de date p = page.text.replace('{{1er}}', '1').replace('{{er}}', '') # Récupération des infos n = self.re_modele.search(p) if n: mod = BeBot.modeletodic(n.group(0)) categorie = n.group(2).replace('_', ' ') # Remise au propre de la casse categorie = categorie[0].upper() + categorie[1:].lower() date = datetime.datetime(1970, 1, 1) if 'date' in mod: o = self.re_date.search(mod['date']) if o: try: jour = int(o.group(1)) mois = BeBot.moistoint(o.group(2)) annee = int(o.group(3)) except: pywikibot.error("Problème de conversion de la date '%s' sur [[%s]]" % (o.group(0), page.title())) return False date = datetime.datetime(annee, mois, jour) else: pywikibot.error("Impossible de reconnaitre le format de date pour %s" % page.title()) return False # Sauvegarde curseur = self.conn.cursor() req = 'INSERT INTO %s ' % self.nom_base \ + '(titre, label, date) VALUES ("%s", "%s", "%s")' \ % (page.title(), categorie, date) if self.debug: #pywikibot.output("Ajout de %s" % page.title()) print('.',end="",flush=True) return try: curseur.execute(req) except sqlite3.Error as e: pywikibot.error("Erreur lors de l'INSERT :\n%s" % (e.args[0])) self.conn.commit() return True if page.namespace() == 0: pywikibot.error("Impossible de trouver le modèle AdQ/BA sur l'article %s" % page.title()) return False
def main(): parser = argparse.ArgumentParser(prog='bebot') parser.add_argument('--debug', action='store_true', default=False, help="Activate debug mode (no publication)") args = parser.parse_args() site = pywikibot.Site() if BeBot.blocage(site): sys.exit(7) spt = Stats_ProjetTraduction(site, args.debug) spt.run()
def get_infos(self, page, cattoa): """ Recherche toutes les informations nécessaires associées à une page """ infos = { 'page': page.title(), \ 'label': cattoa, \ 'taille': BeBot.taille_page(page), \ 'traduction': self.traduction(page), \ } return infos
def run(self): NB_AJOUTS = 0 RETRAITS = True connus = BeBot.charger_bdd(self.db, self.nom_base, champs=u'page') connus = map(self.normaliser_page, connus) self.total_avant = len(connus) ordre_cats = [ u'AdQ', u'BA', u'?' ] for cat in self.cat_qualite: categorie = pywikibot.Category(self.site, cat) cpg = pagegenerators.CategorizedPageGenerator(categorie, recurse=False) try: i = self.categories_de_qualite[self.langue].index(cat) except: i = 2 cattoa = ordre_cats[i] for p in pagegenerators.DuplicateFilterPageGenerator(cpg): if NB_AJOUTS < 2000: if p.namespace() == 0: page = p elif p.namespace() == 1: # Pour EN:GA et IT:FA page = p.toggleTalkPage() else: continue if page.isRedirectPage(): page = page.getRedirectTarget() title = page.title() if title not in connus: #Comparaison avec le contenu de la bdd infos = self.get_infos(page, cattoa) NB_AJOUTS += 1 if infos is not None: self.nouveau.append(infos) else: connus.remove(title) self.connaitdeja.append( \ { 'page': title, \ 'label': cattoa } ) # Ils ne seront pas ajoutés else: pywikibot.output("Limite d'ajouts atteinte avec "+p.title()) RETRAITS = False break # On retire ceux qui ont disparus if RETRAITS: pywikibot.output('Retraits : '+str(connus)) for c in connus: self.req_bdd(c, 'delete') self.connus = len(connus) pywikibot.log( u"Total: %i ajouts ; %i déjà connus ; %i retraits." \ % (len(self.nouveau), len(self.connaitdeja), len(connus)) )
def main(): site = pywikibot.getSite() if BeBot.blocage(site): sys.exit(7) debug = False if len(sys.argv) == 2 and sys.argv[1] == "debug": debug = True elif len(sys.argv) != 1: pywikibot.warning("Nombre de paramètres incorrectes") sys.exit(1) site.login() tm = Trad_maintenance(site, debug) tm.run() pywikibot.output(tm)
def traduction(self, page): """ Donne la page de suivi ou l'interwiki vers fr """ if self.langue == 'fr': pt = BeBot.togglePageTrad(page) if pt.exists(): return pt.title() else: return None else: res = self.interwikifrRE.search(page.text) if res is not None: return res.group('iw') else: return None
def main(): site = pywikibot.Site() if BeBot.blocage(site): sys.exit(7) if len(sys.argv) <= 1: pywikibot.output("Syntaxe: infolettre_pddis.py MAGAZINE [DEBUG]") sys.exit(1) debug = False nbarg = len(sys.argv) infolettre = "" for par in sys.argv: if par.lower() == "debug": debug = True else: lettre = sys.argv[1].lower() bw = Infolettre(site, lettre, debug) bw.run()
def main(): site = pywikibot.Site() if BeBot.blocage(site): sys.exit(7) debug = False if len(sys.argv) > 4 or len(sys.argv) < 3: pywikibot.error("Syntaxe: atom_labellisations.py BASE_SQLITE FLUX_ATOM [DEBUG]") sys.exit(1) bddsqlite = sys.argv[1] fluxatom = sys.argv[2] for par in sys.argv: if par.lower() == "debug": debug = True al = Atom_Labellisations(site, bddsqlite, fluxatom, debug) al.run()
def __init__(self, site, log): self.resume = u"Recherche et suivi des traductions issues d'un article labellisé" self.resumeListing = u"Mise à jour du suivi des traductions issues d'un article labellisé" self.site = site self.log = log self.candidats = [] # Liste des pages de traduction contenant aussi un modele lien + le code langue commun self.tradQualite = [] # Les traductions de qualité connues # RE self.modeleLienRE = re.compile("\{\{(Lien (AdQ|BA)|Link (FA,BA))\|(\w+)\}\}", re.LOCALE) self.modeleTradRE = re.compile("\{\{(Traduction/Suivi|Translation/Information)[^\|\}}]*\|(\w+)\|", re.LOCALE) self.traductions = [] # Pages en cours de traduction cats = [u"Article à traduire", u"Article à relire", u"Article en cours de traduiction", u"Article en cours de relecture"] for cat in cats: c = pywikibot.page.Category(self.site, u"Catégorie:"+cat) for t in c.members(): self.traductions.append(t) cats = [] self.ignor_list = u'' # On ignore les pages qui ont déjà le paramètre adq/ba tmp = [] c1 = pywikibot.Category(self.site, u"Catégorie:Traduction d'un Article de Qualité") cats.append(pagegenerators.CategorizedPageGenerator(c1)) c2 = pywikibot.Category(self.site, u"Catégorie:Traduction d'un Bon Article") cats.append(pagegenerators.CategorizedPageGenerator(c2)) gen = pagegenerators.DuplicateFilterPageGenerator(pagegenerators.CombinedPageGenerator(cats)) gen = pagegenerators.PreloadingGenerator(gen, step=125) for tion in gen: a = BeBot.togglePageTrad(tion).title() tmp.append(a.replace('(', '\\x28').replace(')', '\\x29')) #Remplacement des parenthèses à cause d'un problème de comparaison de chaine utf-8 ; ex : Timée (Platon) self.tradQualite.append(tion) self.ignor_list += u' %s ;;' % a #Pages de traductions d'articles de qualité classées par statut self.trads = [ [], [], [], [], [], [] ] #Traductions terminées sans label, en attente de label, ou labellisées self.term_et_label = [ [], [], [] ]
#!/usr/bin/python # -*- coding: utf-8 -*- import re, sys import BeBot import pywikibot """ Supprime un modèle et ses appels d'inclusion """ site = pywikibot.getSite() nom = u"Demande de traduction" # renom = re.compile('{{'+nom+'}}', re.IGNORECASE|re.MULTILINE) renom = re.compile("{{" + nom + "\|?[^}/]*?}}", re.IGNORECASE | re.MULTILINE) modele = pywikibot.Page(site, u"Modèle:" + nom) if not modele.exists(): pywikibot.error(u"Le modèle {nom} n'existe pas".format(nom=nom)) sys.exit(2) debug = True # Retrait des transclusions for b in modele.getReferences(follow_redirects=False, onlyTemplateInclusion=True, content=True, total=9): a = renom.sub(r"", b.text) BeBot.diff(b.text, a) b.text = a BeBot.save(b, commentaire=u'Retrait du modèle "{nom}"'.format(nom=nom), debug=debug) BeBot.delete(modele, u'Retrait du modèle "{nom}"'.format(nom=nom), debug=debug)
def main(): site = pywikibot.getSite() if BeBot.blocage(site): sys.exit(7) cm = CategorieMasquee(site, u'Catégorie:Numéro du Wikimag') cm.run()
def suppr_cat(cat): for b in cat.subcategories(): suppr_cat(b) BeBot.delete(cat, comment.format(nom=cat.title()), debug=debug)
TODO: * total de bot actif / total * contribution moyenne """ site = pywikibot.Site() p = pywikibot.Page(site, 'Utilisateur:BeBot/Activité des bots') # Page des résultats classement = {} # classement par nb de modifs last = {} # date de dernière modif lim_jours = 182 # nombre de jours à prendre en compte peuactifs = {} # bots peu actifs lim_peu = 10 # limite de modifications pour les bots peu actifs bots = pywikibot.Category(site, 'Catégorie:Wikipédia:Bot/Autorisé') for b in bots.articles(): nb, derniere = BeBot.userdailycontribs(site, b.title(), days=lim_jours) nom = b.title(withNamespace=False) if nb > lim_peu: classement[nom] = nb last[nom] = derniere else: peuactifs[nom] = nb classement = sorted(classement.items(), key=itemgetter(1), reverse=True) # Affichage des résultats t = '{{|class=\"wikitable sortable\"\n|+calculé le {date}\n!Nom!!Contribs ces {x} derniers jours!!Timestamp de dernière modif'.format(date=datetime.date.today().isoformat(),x=lim_jours) for nom, nb in classement: t += '\n|-\n|{{u|%s}}||%d||%s' % (nom, nb, last[nom]) t += '\n|}'
#!/usr/bin/python # -*- coding: utf-8 -*- import BeBot import pywikibot site = pywikibot.Site() page = pywikibot.Page(site, u'Utilisateur:BeBot/Test') page.text = ' ' BeBot.save(page, commentaire=u'Login', minor=True)