MediaWiki revisions API: lấy lịch sử sửa không mất revision
MediaWiki revisions API là phần prop=revisions của action=query, trả từng lần sửa của một trang wiki kèm mã định danh và thời điểm. Bài này viết cho người theo dõi thay đổi của các bài Wikipedia, cần lấy đủ lịch sử mà không sót hay trùng revision khi danh sách dài. ProxyVN gọi API thật của Wikipedia tiếng Việt ngày 05/11/2026, lấy trọn 201 revision của một trang qua 11 lượt continuation và kiểm từng mắt xích parentid.
MediaWiki revisions API: mục tiêu và phạm vi không lặp
Phần này chốt bài toán, đầu ra và ranh giới với các bài gần chủ đề.
Bài toán cần giải
Một nhóm biên tập theo dõi vài chục bài Wikipedia về ẩm thực và địa danh. Họ muốn biết bài nào vừa bị sửa, ai sửa, sửa lúc nào, và có lần sửa nào bị quản trị viên ẩn. Script cũ chỉ lấy 50 revision mới nhất, nên bài có lịch sử dài bị cắt mà không ai biết.
Đầu ra nghiệm thu
Đầu ra là bảng gồm pageid, revid, parentid, timestamp, size, sha1, minor và các cờ ẩn. Đi kèm là quy trình continuation đã kiểm: số lượt gọi, số revision, không có revid trùng, mọi parentid trỏ đúng revision đứng trước, và revision đầu có parentid bằng 0.
Ranh giới với bài Pageviews và Wikidata
Bài Wikimedia Pageviews API trong cùng cụm đếm lượt xem. Bài Wikidata SPARQL bằng Python truy vấn thực thể. Bài này chỉ nói về lịch sử sửa: ID, thời điểm và chuỗi cha con. Bài không dựng parser wikitext, không phân tích nội dung thay đổi.
Giới hạn của lab
Lab gọi API thật, không đăng nhập, nghỉ 1 giây giữa các lời gọi, gửi maxlag bằng 5. Trang mẫu chính là Bún chả trên Wikipedia tiếng Việt. Revision bị ẩn tìm qua nhật ký xóa công khai trong ngày. Tài khoản không đăng nhập chỉ thấy những gì công khai, nên lab không kiểm được nội dung của revision bị ẩn.
Ai nên đọc
Người làm biên tập, kiểm chứng thông tin hay nghiên cứu về cộng đồng wiki. Kỹ sư dữ liệu xây bảng thay đổi cho nhiều trang. Người viết bot đọc lịch sử trang, cần biết tham số nào chỉ chạy được với một trang và tham số nào chạy với nhiều trang.
Những gì bài không làm
Bài không hướng dẫn sửa trang qua API, không nói về OAuth, không dùng EventStreams để nghe thay đổi theo thời gian thực. Bài cũng không tải dump lịch sử đầy đủ. Phạm vi chỉ là đọc revision qua action API với tốc độ nhẹ.
Thuật ngữ dùng trong bài
Pageid là ID của trang, không đổi khi trang được đổi tên. Revid là ID của một lần sửa, tăng dần trên toàn wiki. Parentid là revid của lần sửa ngay trước trên cùng trang. Continuation là cơ chế API trả một mảnh kết quả cùng khóa để lấy mảnh tiếp theo.
Vì sao lịch sử sửa đáng theo dõi
Một bài Wikipedia về món ăn hay địa danh có thể bị sửa sai số liệu, bị chèn quảng cáo, hoặc được bổ sung nguồn mới. Biên tập viên muốn thấy thay đổi đó sớm. Nhà nghiên cứu muốn đo nhịp sửa của cộng đồng. Cả hai cần một bảng revision đủ dòng, có thể so sánh theo thời gian.
Wikipedia tiếng Việt và wiki khác
Lab chạy trên vi.wikipedia.org, nhưng mọi wiki dùng MediaWiki đều có cùng action API. Wiki nội bộ của công ty, Wiktionary hay Wikimedia Commons đều đọc revision theo cùng cách. Khác biệt nằm ở phiên bản MediaWiki và cấu hình quyền, nên khi chuyển sang wiki khác, chạy lại các phép kiểm trong bài.
Lấy revisions có continuation và timestamp để theo dõi thay đổi bài với MediaWiki revisions API
Phần này đi qua lời gọi và cấu trúc response đã chạy.
Nguồn tài liệu đã đọc
Trang API:Revisions trên MediaWiki mô tả các tham số rvprop, rvlimit, rvdir, rvstart, rvend, rvcontinue và các chế độ dùng. Trang API:Continue mô tả cách tiếp tục truy vấn. Lab đối chiếu hai trang này với response thật.
Endpoint và định dạng
Lab gọi https://vi.wikipedia.org/w/api.php với action=query, prop=revisions, format=json, formatversion=2. Formatversion 2 trả pages là mảng thay vì object theo pageid, giá trị boolean là true hoặc false thật. Đọc bằng Python gọn hơn nhiều.
User-Agent và maxlag
Wikimedia yêu cầu User-Agent có tên công cụ và cách liên hệ. Lab dùng tên client chung của dự án kèm website, không dùng email cá nhân. Tham số maxlag bằng 5 yêu cầu máy chủ từ chối khi độ trễ sao chép cơ sở dữ liệu vượt 5 giây. Bot lịch sự nên gửi tham số này.
Ví dụ request bằng Python
import requests, time
s = requests.Session()
s.headers["User-Agent"] = "ProxyVN-docs-lab/1.0 (https://proxy.vn/; low-volume documentation test) python-requests"
API = "https://vi.wikipedia.org/w/api.php"
def q(**p):
p.update(action="query", format="json", formatversion="2", maxlag="5")
r = s.get(API, params=p, timeout=30)
time.sleep(1.0)
return r.json()
d = q(titles="Bún chả", prop="revisions", rvprop="ids|timestamp|size|sha1|flags",
rvlimit="20", rvdir="newer")
pg = d["query"]["pages"][0]
print(pg["pageid"], pg["revisions"][0], d.get("continue"))
Một revision trong response
Revision đầu tiên của Bún chả có revid 73602, parentid 0, minor true, timestamp 2005-10-23T07:15:18Z, size 719, sha1 138563bd0642cc0a10992c315023eaa42de1d13a. Size là số byte của nội dung. Sha1 là băm của nội dung, dùng để phát hiện hai revision có nội dung giống hệt.
Timestamp theo UTC
Timestamp có hậu tố Z, tức là UTC. Lần sửa mới nhất của Bún chả là 2026-07-02T15:14:43Z, tức 22 giờ 14 phút cùng ngày theo giờ Việt Nam. Bảng nên lưu UTC, chỉ đổi múi giờ khi hiển thị.
Batchcomplete và warnings
Response có thể có batchcomplete bằng true, nghĩa là mọi module trong lượt này đã trả đủ phần của mình. Khối warnings xuất hiện khi tham số bị bỏ qua hoặc sắp bị ngừng hỗ trợ. Lab ghi log mọi warnings, vì đó thường là dấu hiệu sớm của thay đổi phía API.
Lỗi trả trong JSON với mã 200
Lỗi invalidparammix ở phần sau trả trong khối error của JSON, mã HTTP vẫn là 200. Pipeline không được chỉ kiểm r.ok. Phải đọc khối error trước khi đọc query. Bỏ qua bước này, script sẽ ném KeyError ở dòng đọc pages và che mất thông điệp lỗi thật.
Rvdir quyết định thứ tự
Mặc định rvdir là older, tức trả từ mới về cũ. Lab dùng newer để đi từ revision đầu tiên tới mới nhất. Thứ tự này tiện cho việc kiểm parentid, vì mỗi revision chỉ cần so với dòng ngay trước.
Chọn prop=revisions và các trường ID/time cần lấy trong MediaWiki revisions API
Lấy ít trường hơn thì nhanh hơn, nhưng thiếu trường là không kiểm được.
Rvprop tối thiểu

Rvprop tối thiểu
Lab dùng rvprop là ids, timestamp, size, sha1, flags. Ids trả revid và parentid. Flags trả minor. Không lấy content vì bảng theo dõi chỉ cần biết có thay đổi, không cần đọc thay đổi. Content làm response nặng hơn hàng trăm lần.
Thêm user và comment khi cần
Rvprop user và comment cho biết ai sửa và lời tóm tắt sửa. Hai trường này hữu ích cho biên tập viên nhưng có thể bị ẩn. Lab chỉ thêm chúng ở phần kiểm revision bị ẩn, để thấy API báo ẩn ra sao.
Chế độ một trang và nhiều trang
Gửi titles là "Phở|Bún chả" cùng rvlimit 5, API trả lỗi code invalidparammix. Thông báo nói khi nhiều trang được cung cấp, các tham số rvlimit, rvstartid, rvendid, rvdir=newer, rvuser, rvexcludeuser, rvstart, rvend chỉ dùng được với một trang. Đây là ràng buộc quan trọng nhất của API này.
Nhiều trang chỉ lấy revision mới nhất
Bỏ rvlimit, gửi ba tên "Phở|Bún chả|Trang không có xyz", API trả mỗi trang một revision mới nhất. Phở có revid 75647145 lúc 2026-10-17T15:30:29Z. Bún chả có 75261517 lúc 2026-07-02T15:14:43Z. Trang bịa trả missing true, không có pageid.
Hai pha cho nhiều trang
Từ ràng buộc trên, quy trình hợp lý có hai pha. Pha một gửi nhiều trang một lời gọi, lấy revid mới nhất của từng trang. Pha hai chỉ với trang có revid mới khác lần trước, gọi riêng từng trang với rvstartid để lấy phần lịch sử còn thiếu.
Rvslots và nội dung nhiều slot
Từ các phiên bản MediaWiki gần đây, nội dung nằm trong slots, slot chính tên là main. Khi lấy content, gửi rvslots bằng main hoặc dấu sao. Lab dùng rvslots main ở phần kiểm revision ẩn. Cờ texthidden nằm trong slot, không nằm ở cấp revision như userhidden.
Rvstart và rvend theo thời gian
Ngoài rvstartid, có thể giới hạn theo thời gian bằng rvstart và rvend. Hai tham số này chỉ dùng với một trang. Lấy revision trong một tháng cụ thể thì đặt rvdir newer, rvstart là đầu tháng, rvend là cuối tháng. Lab chưa chạy bộ lọc này.
Bảng trường cần giữ
Trường |
rvprop |
Lý do giữ |
|---|---|---|
pageid |
tự có |
Khóa trang, không đổi khi đổi tên |
revid |
ids |
Khóa revision |
parentid |
ids |
Nối chuỗi thay đổi |
timestamp |
timestamp |
Thời điểm sửa, UTC |
size |
size |
Biết sửa lớn hay nhỏ |
sha1 |
sha1 |
Phát hiện hoàn tác |
minor |
flags |
Sửa nhỏ do người sửa tự đánh dấu |
*hidden |
user, comment, sha1 |
Biết phần nào bị ẩn |
Trang không tồn tại
Trang bịa trả object có title và missing true. Pipeline phải đọc cờ này, không được giả định mọi phần tử trong pages đều có revisions. Truy cập pg["revisions"] trực tiếp sẽ ném KeyError với trang thiếu.
Đọc continuation cho lịch sử nhiều trang trong MediaWiki revisions API
Phần này là lõi của bài: lấy đủ mà không trùng.
Khối continue

Vòng continuation
Lượt gọi đầu với rvlimit 20 trả 20 revision và khối continue gồm rvcontinue là "20070316155646|487958" và continue là "||". Rvcontinue chứa timestamp và revid của revision tiếp theo. Continue là chuỗi nội bộ API dùng để biết module nào đã xong.
Vòng lặp đã chạy
title = "Bún chả"; revs = []; cont = {}; calls = 0
while True:
d = q(titles=title, prop="revisions", rvprop="ids|timestamp|size|sha1|flags",
rvlimit="20", rvdir="newer", **cont)
calls += 1
pg = d["query"]["pages"][0]
revs += [dict(pageid=pg["pageid"], **r) for r in pg.get("revisions", [])]
if "continue" not in d:
break
cont = dict(d["continue"])
print(calls, len(revs))
Kết quả vòng lặp
Vòng lặp chạy 11 lượt, thu 201 revision. Revision đầu là 73602 năm 2005, revision cuối là 75261517 năm 2026. Không có revid trùng. Danh sách revid tăng dần đúng thứ tự. Lượt cuối không có khối continue, đó là tín hiệu duy nhất để dừng.
Gửi lại toàn bộ khối continue
Cách đúng theo tài liệu là gửi lại mọi khóa trong khối continue cùng tham số gốc. Lab gộp dict(d["continue"]) vào tham số lượt sau. Không tự tạo rvcontinue từ timestamp hay revid của dòng cuối, vì định dạng của nó có thể đổi.
Thử chỉ gửi rvcontinue
Lab thử bỏ continue bằng "||" và chỉ gửi rvcontinue. Lượt hai vẫn trả revision bắt đầu từ revid 487958, parentid 487956, không có cảnh báo. Với một module đơn lẻ như ở đây, thiếu continue không gây lỗi. Khi dùng generator cộng nhiều prop, thiếu nó có thể làm lặp hoặc sót.
Số lượt tỉ lệ với độ dài lịch sử
Với rvlimit 20, 201 revision cần 11 lượt. Trang có 5000 revision sẽ cần 250 lượt nếu giữ mức này. Nghỉ 1 giây mỗi lượt, mất hơn 4 phút cho một trang. Đây là lý do pha một của pipeline chỉ hỏi revid mới nhất, và lịch sử đầy đủ chỉ lấy một lần đầu tiên.
Vì sao không dùng rvlimit max ngay
Rvlimit có thể đặt tới mức max của API. Lab dùng 20 để có nhiều lượt continuation mà kiểm. Trong sản xuất, đặt max giảm số lời gọi. Nếu có lấy content, giới hạn mỗi lượt sẽ thấp hơn, và vòng continuation càng quan trọng.
Dừng giữa chừng và chạy tiếp
Lưu khối continue cuối cùng đã xử lý cùng danh sách revid đã ghi. Nếu script dừng vì mất mạng, lần chạy sau nạp lại khối đó và tiếp tục. Trước khi ghi, bỏ qua revid đã có. Lab không mô phỏng ngắt giữa chừng, đây là quy tắc thiết kế.
Ghi log mỗi lượt
Mỗi lượt nên ghi số revision nhận, revid đầu và cuối của mảnh, và khối continue. Khi có nghi ngờ sót, log cho biết mảnh nào bị thiếu. Với Bún chả, 11 dòng log là đủ để tái lập toàn bộ quá trình.
Khi trang được sửa trong lúc đang lấy
Với rvdir newer, revision mới phát sinh trong lúc lặp sẽ nằm ở cuối, lượt cuối có thể lấy được. Với rvdir older, revision mới nằm ở đầu, vòng lặp đã đi qua chỗ đó nên sẽ không thấy. Lần quét sau phải bắt đầu từ revid lớn nhất đã có để bù.
Giữ pageid, revid và parentid để nối chuỗi thay đổi với MediaWiki revisions API
Chuỗi cha con là phép kiểm mạnh nhất cho việc không mất revision.
Vì sao parentid là phép kiểm mạnh
Đếm số revision chỉ cho biết có bao nhiêu dòng. Nó không cho biết dòng nào bị sót. Parentid thì chỉ đích danh revision nào phải đứng ngay trước. Một mảnh continuation bị mất sẽ để lại một cặp có parentid không khớp, và cặp đó cho biết chính xác khoảng revid cần lấy lại.
Kiểm mắt xích
Với danh sách sắp theo revid tăng, mỗi revision phải có parentid bằng revid của dòng ngay trước. Lab kiểm 200 cặp liền nhau của Bún chả, số mắt xích gãy là 0. Revision đầu có parentid 0, đúng là lần tạo trang.
Mã kiểm
breaks = [(a["revid"], b["revid"], b["parentid"])
for a, b in zip(revs, revs[1:]) if b["parentid"] != a["revid"]]
dups = len(revs) - len({r["revid"] for r in revs})
assert revs[0]["parentid"] == 0 and not breaks and dups == 0
Khi mắt xích gãy
Lab không gặp ca gãy. Gãy có thể do vòng continuation sót một mảnh, do revision bị xóa hẳn khỏi lịch sử, hoặc do trang được nhập lịch sử từ wiki khác. Pipeline không tự sửa. Nó ghi cặp gãy và lấy lại khoảng đó bằng rvstartid và rvendid để xem sót hay xóa.
Mắt xích gãy không phải lúc nào cũng là lỗi
Khi quản trị viên xóa hẳn một trang rồi khôi phục một phần lịch sử, hoặc khi hai trang được hợp nhất lịch sử, chuỗi parentid có thể không liền mạch. Đây là thao tác hợp lệ trên wiki. Pipeline chỉ cần phân biệt được sót do mình và gãy do nguồn, bằng cách lấy lại khoảng nghi ngờ.
Revid tăng toàn wiki
Revid của Bún chả nhảy từ 73602 lên hàng chục triệu. Khoảng cách lớn là bình thường vì revid đếm chung cho mọi trang trên wiki. Không dùng hiệu revid để đoán số lần sửa của một trang.
Pageid ổn định hơn tên
Khi trang đổi tên, pageid giữ nguyên, các revision vẫn thuộc pageid đó. Bảng nên dùng pageid làm khóa trang, lưu tên chỉ để đọc. Nếu dùng tên làm khóa, một lần đổi tên sẽ tách lịch sử thành hai trang trong bảng.
Size và sha1 nói về loại thay đổi
Size lần đầu của Bún chả là 719 byte, lần cuối là 12163 byte. Hiệu size giữa hai revision liền nhau cho biết sửa lớn hay nhỏ. Hai revision không liền nhau có cùng sha1 thường là dấu hiệu hoàn tác về một bản cũ.
Minor là cờ tự khai
Cờ minor do người sửa tự đánh dấu. Revision đầu của Bún chả có minor true dù đó là lần tạo trang. Không dùng minor để lọc thay đổi quan trọng. Hiệu size và sha1 là tín hiệu khách quan hơn.
Không có chuỗi rẽ nhánh
Lịch sử MediaWiki là tuyến tính trên mỗi trang. Mỗi revision có đúng một parentid. Không có nhánh như git. Vì vậy kiểm mắt xích đơn giản như trên là đủ.
Đối soát revision ẩn hoặc thiếu content theo quyền nguồn trong MediaWiki revisions API
Phần này kiểm những gì API trả khi quản trị viên đã ẩn một phần revision.
Tìm revision bị ẩn qua nhật ký

Revision bị ẩn
Lab gọi list=logevents với letype là delete, leaction là delete/revision, lelimit 10. Nhật ký công khai trả các trang như Thành phố đô thị Bari, Bari (tỉnh), Bạc Liêu (tỉnh). Mỗi mục có danh sách ids và params.new cho biết phần nào bị ẩn: content, comment, user.
Revision ẩn cả ba phần
Hai revision 75691089 và 75691220 của Thành phố đô thị Bari có bitmask 7 trong nhật ký. Gọi revids với rvprop có user, comment, sha1, content, API trả userhidden, commenthidden, sha1hidden đều true. Slot main có texthidden true, không có content. Size vẫn trả 10662 và 10663, parentid vẫn có.
Bitmask trong nhật ký
Nhật ký ghi bitmask 7 cho Bari và 2 cho Bạc Liêu. Bitmask là tổng các cờ ẩn: nội dung, lời tóm tắt và người sửa. Đọc các khóa content, comment, user trong params.new dễ hiểu hơn tự giải bitmask, và đó cũng là dạng lab dùng.
Revision chỉ ẩn comment
Revision 75692401 của Bạc Liêu (tỉnh) có bitmask 2. API trả commenthidden true, nhưng user, sha1 và content vẫn có. Content dài 102370 ký tự, size 126766 byte. Hai con số khác nhau vì size đếm byte UTF-8, còn len trong Python đếm ký tự.
Ẩn không làm mất revision
Trong cả hai ca, revision vẫn nằm trong lịch sử với revid và parentid. Mắt xích không gãy. Bảng theo dõi vẫn ghi đủ dòng, chỉ để trống các trường bị ẩn và bật cờ tương ứng.
Revid không tồn tại
Gọi revids là 999999999 trả badrevids với revid đó và missing true. Không có lỗi HTTP. Pipeline đọc khối badrevids để biết revid nào không tìm thấy.
Nhật ký là nguồn chính thức về việc ẩn
Thay vì dò từng revision để xem cờ hidden, đọc list=logevents với letype delete cho biết revision nào vừa bị ẩn và ẩn phần nào. Nhật ký công khai trả title, ids và params.new với các khóa content, comment, user, restricted. Pipeline có thể dùng nhật ký để cập nhật cờ cho các dòng đã lưu.
Revision đã lưu trước khi bị ẩn
Nếu pipeline đã lưu user hay comment của một revision trước khi nó bị ẩn, nên xóa hoặc che các trường đó khi nhật ký báo ẩn. Giữ lại dữ liệu mà cộng đồng đã quyết định ẩn đi ngược với lý do ẩn, nhất là khi lý do là thông tin cá nhân.
Không cố lấy phần bị ẩn
Phần bị ẩn là quyết định của quản trị viên, thường vì vi phạm bản quyền, thông tin cá nhân hoặc nội dung xúc phạm. Tài khoản thường không xem được. Pipeline không nên tìm cách khôi phục nội dung đó từ nguồn khác như bản lưu trữ hay mirror.
Bảng các ca ẩn
Revision |
Phần ẩn |
API trả |
Còn lại |
|---|---|---|---|
75691089 |
user, comment, nội dung |
userhidden, commenthidden, sha1hidden, texthidden |
revid, parentid, size |
75691220 |
user, comment, nội dung |
như trên |
revid, parentid, size |
75692401 |
comment |
commenthidden |
user, sha1, content |
999999999 |
không tồn tại |
badrevids missing |
không có |
Đầu ra nghiệm thu: Bảng pageid revid parentid timestamp và quy trình tiếp tục không mất revision của MediaWiki revisions API
Phần này liệt kê điều kiện để coi bảng là xong.
Tệp bảng revision
Mỗi dòng một revision, gồm pageid, revid, parentid, timestamp, size, sha1, minor, userhidden, commenthidden, sha1hidden, texthidden. Lab lưu revs_bun_cha.json với 201 dòng.
Kiểm continuation
Ghi số lượt gọi và số revision. Bún chả có 11 lượt, 201 revision, lượt cuối không có continue. Không revid trùng, revid tăng dần.
Kiểm chuỗi
Revision đầu có parentid 0. Mọi revision sau có parentid bằng revid trước. Số mắt xích gãy là 0.
Kiểm ẩn
Revision bị ẩn vẫn có dòng, trường bị ẩn để trống, cờ bật đúng. Lab kiểm với ba revision lấy từ nhật ký xóa trong ngày.
Tệp nhật ký đi kèm
Lab lưu logevents.json chứa các mục xóa revision trong ngày. Tệp này giải thích vì sao một số dòng trong bảng có cờ hidden. Người đọc bảng không cần gọi lại API để biết nguồn của cờ.
Bảng nghiệm thu của lab

Nghiệm thu lịch sử
Hạng mục |
Kết quả 05/11/2026 |
|---|---|
Nhiều trang cùng rvlimit |
Lỗi invalidparammix |
Nhiều trang không rvlimit |
Mỗi trang 1 revision mới nhất |
Lịch sử Bún chả |
11 lượt, 201 revision |
Revid trùng |
0 |
Mắt xích gãy |
0, revision đầu parentid 0 |
Revision ẩn 3 phần |
Cờ hidden, size và parentid còn |
Revid bịa |
badrevids missing |
Những gì lab chưa chạy
Lab chưa thử generator lấy nhiều trang cùng lúc, chưa thử trang có hàng chục nghìn revision, chưa thử rvslots ngoài main, chưa thử đăng nhập với quyền xem nội dung ẩn. Lab cũng chưa mô phỏng việc ngắt giữa vòng continuation rồi chạy tiếp.
Vận hành MediaWiki revisions API trong pipeline theo dõi thay đổi
Pipeline theo dõi chạy định kỳ, nên chỉ lấy phần mới.
Pha một: hỏi revid mới nhất
Gom tối đa số tên trang API cho phép trong một lời gọi, không rvlimit, lấy revid mới nhất của từng trang. So với revid lớn nhất đã lưu. Trang không đổi thì bỏ qua.
Pha hai: lấy phần thiếu
Với trang đã đổi, gọi riêng với rvdir newer và rvstartid bằng revid lớn nhất đã có. Revision đầu tiên trả về chính là revision đã có, bỏ qua nó. Các revision sau là phần mới. Kiểm parentid của revision mới đầu tiên khớp với revid đã có.
Lịch chạy
Trang ít người sửa thì chạy mỗi ngày là đủ. Trang thời sự có thể chạy mỗi giờ. Pha một rất nhẹ, nên chi phí chủ yếu nằm ở số trang đã đổi.
Bảng trạng thái theo trang
Ngoài bảng revision, giữ một bảng nhỏ mỗi trang một dòng: pageid, tên hiện tại, revid lớn nhất đã lưu, thời điểm quét cuối, số revision. Pha một so revid mới nhất với cột revid lớn nhất. Bảng này nhỏ, đọc nhanh, và là nơi đầu tiên để xem khi pipeline có vấn đề.
Trang bị xóa hoặc đổi tên
Pha một có thể trả missing true cho trang từng tồn tại. Có thể trang đã bị xóa hoặc đổi tên mà không để chuyển hướng. Gọi lại bằng pageids thay vì titles để phân biệt. Nếu pageid vẫn còn, trang chỉ đổi tên. Nếu pageid cũng mất, trang đã bị xóa.
Xử lý lỗi và maxlag
Khi máy chủ trễ, API trả lỗi maxlag kèm Retry-After. Chờ đúng thời gian đó rồi gọi lại. Lỗi invalidparammix là lỗi mã, sửa mã. Lỗi mạng thử lại có giãn cách, không quá ba lần.
Gom trang theo wiki
Nếu theo dõi trang trên nhiều wiki, mỗi wiki là một endpoint riêng, revid không so được giữa các wiki. Bảng revision phải có cột wiki, khóa thật là cặp wiki và revid. Pipeline chạy pha một riêng cho từng wiki.
Proxy ở tầng mạng
Action API của Wikipedia công khai, gọi thẳng là cách nên dùng. Proxy chỉ cần khi mạng nội bộ bắt buộc. Dùng nhiều IP để tăng tốc độ gọi là trái chính sách của Wikimedia. Cách ghi chuỗi proxy có ở bài định dạng proxy, vai trò proxy trong thu thập có ở bài Web Scraping proxy là gì. Khi cần IP Việt Nam cho tác vụ khác, anh em có thể mua proxy tại trang chủ ProxyVN.
Không lấy content khi không cần
Pipeline theo dõi chỉ cần ids, timestamp, size, sha1. Lấy content cho mọi revision làm dữ liệu tải về lớn gấp hàng trăm lần và tạo tải không cần thiết cho máy chủ. Chỉ lấy content của revision cụ thể khi biên tập viên muốn mở xem thay đổi.
Khóa phiên bản
Lab chạy Python 3.12.10, requests 2.34.2. Action API ổn định qua nhiều năm, nhưng formatversion 2 và tên tham số có thể đổi. Giữ một bộ test đọc JSON đã lưu để phát hiện sớm khi schema đổi.
Lấy đến khi không còn khối continue, kiểm parentid từng cặp, ghi revision ẩn với cờ thay vì bỏ qua. Đó là cách lịch sử không bị mất dòng.
MediaWiki revisions API: câu hỏi thường gặp
Các câu dưới đây gom những điểm hay bị hỏi.
Có cần đăng nhập không?
Không với dữ liệu công khai. Đăng nhập chỉ cần khi có quyền xem nội dung bị ẩn hoặc cần hạn mức cao hơn cho bot.
Vì sao lấy nhiều trang thì lỗi rvlimit?
API chỉ cho rvlimit và các tham số lọc theo thời gian với một trang. Nhiều trang thì chỉ lấy revision mới nhất.
Dừng vòng lặp khi nào?
Khi response không còn khối continue. Không dừng theo số dòng trả về.
Revision bị ẩn có làm gãy chuỗi không?
Không. Revid và parentid vẫn có. Chỉ user, comment, sha1 hay nội dung bị ẩn.
Có nên tự dựng rvcontinue?
Không. Gửi lại nguyên khối continue mà API trả.
Size và độ dài content khác nhau là lỗi?
Không. Size đếm byte, độ dài chuỗi Python đếm ký tự. Tiếng Việt có dấu tốn nhiều byte hơn mỗi ký tự.
Có lấy được lịch sử nhiều trang trong một lời gọi không?
Chỉ lấy được revision mới nhất của mỗi trang. Lịch sử đầy đủ phải gọi từng trang.
Formatversion 2 có bắt buộc không?
Không bắt buộc nhưng nên dùng. Pages là mảng và boolean là true false thật, mã đọc gọn và ít lỗi hơn.
Lấy được nội dung thay đổi giữa hai revision không?
Có endpoint so sánh riêng của MediaWiki. Bài này không dùng nó. Với bảng theo dõi, size và sha1 thường đủ để biết có cần mở xem hay không.
Có giới hạn tốc độ cụ thể không?
Lab không chạm giới hạn ở nhịp 1 giây mỗi lời gọi. Wikimedia khuyên gọi tuần tự, không song song, và gửi maxlag. Theo đúng hai điều đó là đủ cho pipeline nhỏ.
MediaWiki revisions API và những điều cần nhớ
MediaWiki revisions API cho lịch sử sửa đầy đủ khi gọi từng trang với continuation tới lúc hết khối continue, rồi kiểm parentid của từng cặp revision. Nhiều trang chỉ dùng để hỏi revid mới nhất, revision bị ẩn vẫn ghi dòng với cờ hidden, và pageid là khóa trang ổn định hơn tên. Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam khuyên anh em giữ phép kiểm chuỗi cha con trong mọi pipeline dùng MediaWiki revisions API.