Wikipédia:Pywikibot/A Pywikibot interaktív használata
Ezen az oldalon egy technikai leírást olvashatsz a Wikipédia szerkesztéséről. Tartsd szem előtt, hogy nem minden ajánlott, ami technikailag megvalósítható! |
A Pywikibot keretrendszert alapvetően a kész scriptek futtatására vagy saját scriptek fejlesztésére használhatjuk, de van egy érdekes interaktív használati módja is. Ez alkalmi feladatok megoldására lehet hasznos olyanoknak, akik jártasak a Python programozási nyelvben, és kicsit mélyebben ismerik a keretrendszert. Akkor érdemes ehhez a módszerhez folyamodni, ha a kódot nem szándékozunk újrahasznosítani, illetve ki akarjuk használni a felület interaktivitását a kísérletezéshez.
- Tartsd szem előtt, hogy ez itt nem egy mindenre kiterjedő leírás, csak egy esettanulmány, amiből ihletet nyerhetsz.
- Mivel az interaktív használat célja a gyors barkácsmunka, ezek a hevenyészett utasítások nem követik a PEP8-at vagy más formai útmutatót, nem a kód szépsége volt a lényeg, hiszen csak egyszeri használatra készült. A szóközöket azért kitettem, hogy olvashatóbb legyen.
- A kódhoz vezető kísérletek itt nem láthatóak, csak az eredmény. Természetesen hazugság lenne azt állítani, hogy a sorok ilyen letisztultan pattantak ki egymás után a szerző fejéből, a tesztkiírásokat mellőztem, hogy a lényeg látsszék.
Előkészületek
szerkesztés- Feltételezzük, hogy van egy telepített Pywikibot-példányod, és botként be vagy jelentkezve benne.
- Állj abba a könyvtárba (pl. Total Commanderrel), ahova a botot telepítetted.
- Innen indíts el egy Python-értelmezőt (pl. egy parancssori ablakban add ki a python parancsot, vagy indítsd el az IDLE-t).
A sorok elején álló >>> jeleket a Python akkor jeleníti meg, ha új parancsot vár, a ... jeleket pedig akkor, ha egy be nem fejezett parancs folytatását. A végén üres enterrel tudjuk jelezni, hogy kész a ciklus vagy a függvény.
Példa
szerkesztésA feladat
szerkesztésOlvassuk be a Kategória:Magyar vonatkozású kisbolygók cikkeit, és határozzuk meg a kisbolygók névadóját, majd hozzuk létre ezekből a cikkekből a Kategória:Magyarok, akikről kisbolygót neveztek el kategóriát!
A megoldás
szerkesztésA megoldás a Pywikibot 2023 elején aktuális 8.0.0 verziójában készült. Mivel menet közben sokat kell kézzel javítgatni, az interakciót választjuk. Az feltűnik, hogy az infoboxban megjelenő névadó általában nem az oldal szövegéből, hanem a Wikidatából jön, de nem minden esetben. Ezért ahol lehet, onnan vesszük a nevet, de ebből néhány esetben átirányítás lesz.
Előkészületként létrehozzuk a kategóriánkat reprezentáló objektumot:
>>> import pywikibot as p
>>> site = p.Site()
>>> cat = p.Category(site, 'Magyar vonatkozású kisbolygók')
Végigmegyünk a kategória lapjain, és keressük a P138 (névadó) tulajdonság értékét. A próbák azt mutatják, hogy nem mindig van ilyen, ilyen esetben kiírjuk a lap címét kézi feldolgozásra. Ha van névadó magyar címkével, akkor hozzáfűzzük a készülő lapunk szövegéhez.
>>> text = ''
>>> for m in cat.members():
... claim = m.get_best_claim('P138')
... try:
... item = claim.getTarget()
... except AttributeError:
... print(m.title())
... continue
... try:
... hu = item.labels['hu']
... text += '* [[' + hu + ']]\n'
... except KeyError:
... pass
...
A kész szöveget kiírhatjuk egy lapra:
>>> page = p.Page(site, 'user:BinBot/try')
>>> page.put(text, 'Magyarok, akikről kisbolygót neveztek el')
Íme, az eredmény. Most jön a kézi munka, némi Excel-támogatással: nem emberről szóló lapok és duplikátumok törlése, átirányítások, egyértelműsítések javítása. Közben hozzáadjuk azokat a kisbolygókat a laphoz, amelyekhez nem találtunk névadót a Wikidatán, és ezért kiírtuk a címüket a képernyőre. A legegyszerűbb a Pythont hívni segítségül (habár kiírhattuk volna rögtön ebben a formátumban is):
>>> text = """
... 14181 Koromházi
... 68144 Mizser
... 72071 Gábor
... 73511 Lovas
... 75555 Wonaszek
... 75823 Csokonai
... 82656 Puskás
... # Van még jó sok, de rövidítettem, hogy a lényeget lássuk.
.... """
newtext = ['* [[' + s + ']]\n' for s in text.split('\n')]
>>> for sor in newtext:
... print(sor)
...
Ezekhez manuálisan kell nevet keresni. Amikor végül elkészült a listánk, és van több mint 150 cikk rajta, kiléphetünk az interaktív környezetből, és használjuk a Pywikibot category scriptjét a kategóriák hozzáadásához:
python pwb.py category add -links:user:BinBot/try
A script indítés után fogja kérni a hozzáadandó kategória nevét.
Elavult példa
szerkesztésAz itt látható kód a ma már nyugdíjazott compat (leánykori nevén trunk) verzióban készült. A most támogatott core verzióban értelemszerű módosításokkal használható. Például import wikipedia helyett import pywikibot kellene az elejére. A gondolatmenetet mutatja.
A feladat
szerkesztésA Szerkesztő:Bináris/Kék és zöld görög katolikusok oldalon fel van sorolva egy csomó cikk címe #[[Cím]] alakban. Írjuk oda mindegyik után zárójelben a lapra mutató hivatkozások számát!
A megoldás
szerkesztés>>> import wikipedia as w # Interaktív használathoz kényelmesebb egy betű, mint egy beszédes szép név.
'''Ez a három sor az alapeljárás, ahogy az alapértelmezett wikinkből megszerezhetjük egy cikk szövegét:'''
>>> site = w.getSite()
>>> p = w.Page(site, u'Szerkesztő:Bináris/Kék és zöld görög katolikusok')
>>> text = p.get()
'''
A bot kódját böngészve megtudhatjuk, hogy a Page objektum getReferences() metódusa sorolja fel a lapra hivatkozó más lapokat.
Sajnos ez egy generátor, aminek nincs mérete, ezért egy iskolás megszámlálási tétellel gyorsan összeütünk egy rn (refnumber) függvényt a hivatkozó lapok számának meghatározására. Persze aki zsonglőrködni akar, ezt meg is „spórolhatná” a lenti ciklusban egy lambdafüggvénnyel, de a legtöbb embernek valószínűleg gyorsabb ezzel az „álmunkból felverve is” módszerrel.
'''
>>> def rn(p):
... i = 0
... for x in p.getReferences():
... i += 1
... return i
...
'''
Szükségünk lesz egy reguláris kifejezésre, hogy kinyerjük a címeket.
A mintán belül zárójelezzük a keresett tartalmat, az lesz a group(1), míg a teljes megtalált string a #[[...]] csomagolással együtt a group(0) vagy röviden group(). Az u betűt megszokásból teszem ki, itt nincs jelentősége.
'''
>>> import re
>>> r = re.compile(ur'#\[\[(.*?)\]\]')
'''
Most egy ciklussal végigmegyünk a lap szövegében található címeken. A group(1) a listázott cím, amihez kreálunk egy lapobjektumot, és az előbb definiált rn függvénnyel meghatározzuk a rá mutató hivatkozások számát. Egyet levonunk, mert maga ez a lap, ahova a listát írtuk, nem érdekel.
Ezután egy szövegcserével zárójelben a felsorolt cím mögé írjuk a keresett számot. Ehhez nem reguláris kifejezést használunk, mert itt már nem a minta összes előfordulását keressük, hanem a konkrét megtalált címet.
'''
>>> for t in r.finditer(text):
... cim = t.group(1)
... pp = w.Page(site, cim)
... num = rn(pp) - 1
... old = t.group()
... new = old + (" (%d)" % num)
... text = text.replace(old, new)
...
'''
Végül elmentjük. A mentés a bejelentkezett bot nevében történik. Válaszként meglepően sok üzenetet kapunk, amit a scriptek el szoktak nyomni.
''''
>>> p.put(text, u'Hivatkozások száma')
Updating page [[Szerkesztő:Bináris/Kék és zöld görög katolikusok]] via API
(302, 'OK', {u'pageid': 1467324, u'title': u'Szerkeszt\u0151:Bin\xe1ris/K\xe9k \xe9s z\xf6ld g\xf6r\xf6g katolikusok', u'newtimestamp': u'2017-05-09T13:35:23Z', u'contentmodel': u'wikitext', u'result': u'Success', u'oldrevid': 18726976, u'newrevid': 18728308})
Erre igazán kár lett volna programot fejleszteni! Legközelebb valami más feladat lesz, de hasonló eszközökkel oldhatjuk meg.
Az eredmény
szerkesztésTovábbi felhasználási ötletek
szerkesztés- Átirányítások létrehozása Karl May tucatnyi írói álnevéről (A szócikkből egy listába kellett másolni őket, majd a lista minden elemére létrehozni egy cikket ugyanazzal a szöveggel.)
- Keressük meg, hova irányítanak át a felsorolt lapok! (Na jó, nem muszáj így elrontani, hogy kétszer lássunk minden céllapot.)