Thành viên:Alphama/Lập trình Wikipedia/7
Trong bài này bạn sẽ học cách sử dụng Pywikibot.
Điều kiện
- Đã cài đặt Python trên Windows hoặc Linux
- Có tài khoản bot ở Wikipedia
- Trang thử nghiệm Test Bot hoặc trang nháp của thành viên Thành viên:Tên thành viên/nháp
Cài đặt gói pywikibot
Đối với Windows, mở cmd (Command Prompt), gõ dòng lệnh pip install pywikibot, chúng ta sẽ cài gói "pywikibot".
C:\>pip install pywikibot
Đối với Linux, mở "shell" hoặc "command" hoặc "prompt", xem hướng dẫn ở Opening a terminal, gõ dòng lệnh như trên.
Ví dụ đầu tiên
Sau đây là ví dụ chạy bot ở Wikipedia bằng pywikibot, bạn sẽ thay thế thêm nội dung 1 trang dòng chữ "Ví dụ đầu tiên với Pywikibot". Tạo trang tên run_bot.py với nội dung sau.
Lưu ý:
- Thay AlphamaBot bằng tên bot của bạn
import pywikibot
from pywikibot.config import *
site = pywikibot.Site('vi', 'wikipedia') # khai báo ngôn ngữ + dự án
usernames['wikipedia']['vi'] = 'AlphamaBot' # tên bot
page = pywikibot.Page(site, 'Test Bot') # khai báo trang cần thử nghiệm
page.text += '\n\nVí dụ đầu tiên với Pywikibot' # thêm nội dung
page.save('Thêm nội dung vào trang.') # lưu trang với chú thích
“ | Bạn chỉ cần tùy chỉnh biến "page.text" để có thể thay đổi nội dung bài viết bất kỳ ở Wikipedia. | ” |
Thực thi ví dụ
Gõ dòng "python run_bot.py" ở cmd để chạy đoạn code. Đôi khi với Python phiên bản 3, bạn phải dùng "python3 run_bot.py".
Nhập mật khẩu trực tiếp trên console, khi thấy dòng "Password for user AlphamaBot on wikipedia:vi (no characters will be shown):" thì bạn phải tự nhập mật khẩu bằng tay. Có cách nhập tự động, để sau hoặc bạn tự tìm. Tôi không làm cách sau vì sẽ bảo mật hơn cho bạn.
Bộ lọc sai phạm có thể khóa 1 số hành động của Bot.
C:\>python run_bot.py Password for user AlphamaBot on wikipedia:vi (no characters will be shown): Logging in to wikipedia:vi as AlphamaBot Sleeping for 3.5 seconds, xxxx-xx-xx xx:xx:xx Page [[vi:Test Bot]] saved
Chạy bot trên thực tế?
“ | Tôi tin rằng với trình độ của các bạn trẻ hiện nay, từ demo này sẽ tiếp tục được phát triển ra nhiều chức năng hơn nữa. | ” |
Sau đây là demo các chức năng sửa 1 số cụm từ đơn giản, một phần của AlphamaBot hiện nay.
Quy trình thông thường của 1 con bot:
- Đăng nhập
- Kiểm tra trạng thái bot
- Lấy danh sách trang và thực hiện vòng lặp với từng trang trong danh sách
- Biến đổi nội dung trang, lưu trang (nếu có thay đổi nội dung) + kiểm tra trạng thái bot
- Kết thúc, đăng xuất
Lưu ý:
- Code này chưa đầy đủ nhưng có thể chạy trên thực tế
Lưu đoạn mã sau vào 1 tập tin, ví dụ run_bot.py, sau đó cùng cú pháp python run_bot.py để chạy trong cmd (command line).
import sys
import pywikibot
from pywikibot.pagegenerators import * # pagegenerators: tìm kiếm danh sách trang
from pywikibot.config import * # config: cấu hình bot (user, password,...)
#from pywikibot.login import *
import re # gói regex dành cho các biểu thức chính quy
import time
def general_fixes(title, text, summary):
'''
sửa lỗi chung
title: tên trang - string
text: nội dung - string
summary: tóm tắt nội dung sửa đổi - string
return: trả về các biến trên
'''
new_text = text
new_text = re.sub(r'\[\[\s*[Cc]ategory\s*:', '[[Thể loại:', new_text) # thay thế [[Category: --> [[Thể loại:
new_text = re.sub(r'\{\{[Cc]ite\s*book', '{{chú thích sách', new_text)
new_text = re.sub(r'\{\{[Cc]ite\s*web', '{{chú thích web', new_text)
new_text = re.sub(r'\{\{[Cc]ite\s*news', '{{chú thích báo', new_text)
new_text = re.sub(r'\{\{[Cc]ite\s*web', '{{chú thích web', new_text)
new_text = re.sub(r'\{\{[Cc]ite\s*journal', '{{chú thích tạp chí', new_text)
new_text = re.sub(r'\{\{[Cc]ite\s*iucn', '{{chú thích IUCN', new_text)
new_text = re.sub(r'\{\{[Cc]ite\s*doi', '{{chú thích DOI', new_text)
new_text = re.sub(r'\{\{[Cc]ite tweet', '{{chú thích tweet', new_text)
new_text = re.sub(r'\{\{[Rr]eflist', '{{tham khảo', new_text)
new_text = re.sub(r'\<[Rr]eferences\s*\/\>', '{{tham khảo}}', new_text)
new_text = re.sub(r'\[\[[Ff]ile\s*:', '[[Tập tin:', new_text)
new_text = re.sub(r'\[\[[Ii]mage\s*:', '[[Hình:', new_text)
new_text = re.sub(r'\{\{[Tt]axobox', '{{Bảng phân loại', new_text)
new_text = re.sub(r'\{\{[Cc]ommonscat-inline', '{{Thể loại Commons nội dòng', new_text)
new_text = re.sub(r'\{\{[Cc]ommons category-inline', '{{Thể loại Commons nội dòng', new_text)
new_text = re.sub(r'\{\{[Ww]ikispecies-inline', '{{Wikispecies nội dòng', new_text)
new_text = re.sub(r'\{\{[Cc]ommons category', '{{Thể loại Commons', new_text)
new_text = re.sub(r'\{\{[Cc]ommons\s*cat', '{{Thể loại Commons', new_text)
new_text = re.sub(r'==\s*References\s*==', '== Tham khảo ==', new_text)
new_text = re.sub(r'==\s*External\s*links\s*==', '== Liên kết ngoài ==', new_text)
new_text = re.sub(r'==\s*[Ll]iên\s*[Kk]ết\s*[Bb]ên\s*[Nn]goài\s*==', '== Liên kết ngoài ==', new_text)
new_text = re.sub(r'\{\{\s*[Tt]ham(\s*\_*)[Kk]hảo\s*\}\}', '{{tham khảo}}', new_text)
if (new_text != text): summary = '[sửa lỗi chung]'
else: summary = ''
return title, new_text, summary
def check_status(site, bot_name):
"""
kiểm tra trạng thái bot là tắt hay mở
site: biến đối tượng trang - object
bot_name: tên bot - string
return: boolean
"""
# Kiểm tra trạng thái bot ở không gian [[Thành viên:Tên bot/Status]]
# Xem ví dụ cách lưu ở [[Thành viên:AlphamaBot/Status]]
page_name = 'Thành viên:' + bot_name + '/Status'
page = pywikibot.Page(site, page_name)
texts = page.text.split('\n')
try:
pair = [p.strip() for p in texts[1].split('=')]
if (pair[0] == 'active' and pair[1] == '1'):
return True
except: pass
return False
#.......................................................................................
if __name__ == '__main__':
site = pywikibot.Site('vi', 'wikipedia') # khai báo ngôn ngữ + dự án
# ghi đè tham số trong config.py
bot_name = 'AlphamaBot'
usernames['wikipedia']['vi'] = bot_name # tên bot
console_encoding = 'utf-8'
use_api_login = True
put_throttle = 0 # bỏ thời gian chờ giữa các action
maxthrottle = 0 # bỏ thời gian chờ tối đa giữa các action
noisysleep = 30
# Tạo thao tác lưu ảo để đăng nhập và kiểm tra chức năng bot
bot_status_page = 'Thành viên:' + bot_name + '/Status'
page = pywikibot.Page(site, bot_status_page)
page.save('')
if (check_status(site, bot_name) == False):
print('Bot không được kích hoạt! Xem ở [[' + bot_status_page + ']].')
sys.exit() # hàm thoát trong main
# các hàm tạo danh sách
# total: tổng số trang cần tìm
# namespaces: không gian tên
#pages = site.search('toán học', total=50, namespaces=[0]) # tìm trang theo cụm từ
#pages = site.search('insource: 'toán học'', total=50, namespaces=[0]) # tìm trang bằng mã wiki
#pages = RecentChangesPageGenerator(site, total = 50, namespaces=[0]) # tìm trang thay đổi gần đây
#pages = RandomPageGenerator(site, total = 50, namespaces=[0]) # lỗi thời
#pages = site.randompages(total=50, namespaces=[0], redirects=True) # lấy danh sách bài ngẫu nhiên
pages = NewpagesPageGenerator(site, total=1000, namespaces=[0]) # tìm danh sách các trang gần đây ở không gian Chính (bài viết)
step = 5
count = 1
for p in pages:
count += 1
try:
# mỗi 5 trang thì mới kiểm tra trạng thái bot tắt hay mở
if (count%step == 0):
if (check_status(site, bot_name) == False):
print('Bot không được kích hoạt! Xem ở [[' + bot_status_page + ']].')
break
start = time.time()
temp_title = str(p._link)
temp_title = temp_title.strip('[[').strip(']]')
print('Đang xử lý trang: ', temp_title)
page = pywikibot.Page(site, temp_title)
# hàm sửa lỗi chung, thay thế 1 số cụm từ
title, new_text, summary = general_fixes(temp_title, page.text, '')
# hàm sửa nội dung khác
# ...
if (new_text != page.text):
page.text = new_text
end = time.time()
time_label = str(end - start)[0:6] + 's'
page.save(summary = '[[:mw:Manual:Pywikibot|Pywikibot]] + AlphamaModule: ' + summary + ', ' + time_label ) # lưu trang
print('-- Đã lưu!')
else: print('--- Không có gì thay đổi!')
except Exception as e:
print('Lỗi: ', e, p)
print('....................................')
Theo dõi Thành viên:AlphamaBot/Code đa chức năng (pywikibot) để có code mới nhất!
Các chức năng khác có sẵn?
Xem ở Manual:Pywikibot/Scripts.
Kết hợp API và Pywikibot
Pywikibot hiện đã tích hợp gần như đầy đủ chức năng để tương tác với API của các dự án Wikimedia. Tuy nhiên, bạn có thể tự viết các API ngoài và tích hợp nếu muốn!