Trong bài này bạn sẽ học cách sử dụng Pywikibot.

Điều kiện

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

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ế?

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:

  1. Đăng nhập
  2. Kiểm tra trạng thái bot
  3. Lấy danh sách trang và thực hiện vòng lặp với từng trang trong danh sách
    1. 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
  4. 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!