lưu website dạng WARC có provenance và payload digest
lưu website dạng WARC giữ thông điệp thu được cùng dấu vết nguồn thay vì chỉ giữ ảnh chụp giao diện. Tuy vậy một WARC không tự bảo đảm website phát lại đầy đủ. Bài này tạo cặp request và response từ dữ liệu lab, đọc lại payload và phân biệt kiểm toàn vẹn với kiểm replay. ProxyVN hướng dẫn cách kiểm trên dữ liệu mẫu.
lưu website dạng WARC khác chụp ảnh và xuất HTML
Một ảnh chụp ghi lại cách giao diện nhìn thấy tại một thời điểm theo công cụ render. Một tệp HTML riêng giữ phần markup nhưng thường thiếu thông điệp HTTP và quan hệ tài nguyên. WARC là một định dạng đóng gói record phục vụ lưu trữ web theo cấu trúc xác định.
Chọn định dạng phụ thuộc câu hỏi cần trả lời. Nếu chỉ cần duyệt bố cục, ảnh có thể hữu ích; nếu cần kiểm response đã nhận và nguồn của payload, record HTTP có thêm giá trị. Không coi một định dạng thay thế mọi bằng chứng khác trong cùng dự án.
Bộ lab tự tạo URL lab.invalid và một body HTML ngắn, không truy cập domain đó. Nó ghi request cùng response vào WARC rồi đọc lại để so byte. Đây là kiểm ghi đọc định dạng, không phải một crawl live hoặc replay website bằng trình duyệt.
Phân biệt record với tệp WARC
Một tệp có thể chứa nhiều record với các loại khác nhau. Mỗi record có metadata của nó và một block theo kiểu nội dung. Tên tệp archive.warc không cho biết bên trong đã có đầy đủ request, response hay tài nguyên mà trang cần.
Đặc tả WARC 1.1 là nguồn đối chiếu cấu trúc. Ví dụ trong bài chọn version rõ khi tạo writer. Không dựa vào mặc định của thư viện rồi gọi output là một phiên bản định dạng khác chưa kiểm.
Các chỉ số nghiệm thu nên đếm record theo loại và đối chiếu payload cần giữ. Một tệp có kích thước lớn có thể chỉ chứa nhiều trang lỗi hoặc nội dung ngoài scope. Dung lượng lưu không chứng minh chất lượng thu thập.
lưu website dạng WARC từ cặp request và response lab
Cặp thông điệp giúp giữ ngữ cảnh yêu cầu đã tạo ra response. Tuy nhiên request có thể chứa bí mật trong hệ thống thật, nên phạm vi lưu cần được xác định theo dữ liệu. Lab dùng request GET không có token để phép kiểm có thể chia sẻ.

Request và response trong một capture
Tạo writer với phiên bản đã chọn
Mã dưới dùng warcio và dữ liệu tự tạo. URL là một định danh xuất xứ của fixture, không phải endpoint được tải. Payload được biết trước nên có thể so lại sau khi đóng tệp và đọc record.
import io
from warcio.warcwriter import WARCWriter
from warcio.statusandheaders import StatusAndHeaders
url = 'http://lab.invalid/page'
body = b'<html><p>WARC lab</p></html>'
with open('sample.warc', 'wb') as output:
writer = WARCWriter(output, gzip=False, warc_version='1.1')
request = writer.create_warc_record(url, 'request',
payload=io.BytesIO(b''), http_headers=StatusAndHeaders(
'GET /page HTTP/1.1', [('Host', 'lab.invalid')],
is_http_request=True))
writer.write_record(request)
headers = StatusAndHeaders('200 OK', [
('Content-Type', 'text/html'), ('Content-Length', str(len(body)))],
protocol='HTTP/1.1')
record = writer.create_warc_record(url, 'response',
payload=io.BytesIO(body), http_headers=headers,
warc_headers_dict={
'WARC-Concurrent-To': request.rec_headers.get_header('WARC-Record-ID'),
'WARC-Date': request.rec_headers.get_header('WARC-Date')})
writer.write_record(record)
Request và response được nối bằng ID record trong cùng sự kiện capture theo cấu trúc mẫu. Timestamp của hai record được giữ nhất quán trong ví dụ. Không lấy thời điểm chạy parser sau này để thay ngày capture đã ghi.
README warcio là nguồn đối chiếu API writer và iterator. Khóa phiên bản thư viện khi tái hiện. Một package đọc được WARC không tự cho biết mọi trường đã được hệ thống thu thập cung cấp đúng ngữ nghĩa.
Đọc payload trong vòng lặp stream
Iterator đọc tuần tự nên payload cần được xử lý khi record còn ở vị trí phù hợp trong stream. Đừng gom đối tượng record thành list rồi sau khi iterator đã đi hết mới cố đọc mọi body. Trạng thái stream có thể không còn chứa payload như cách người dùng tưởng.
from warcio.archiveiterator import ArchiveIterator
with open('sample.warc', 'rb') as source:
seen = []
for record in ArchiveIterator(source):
payload = record.content_stream().read()
seen.append(record.rec_type)
if record.rec_type == 'response':
assert payload == b'<html><p>WARC lab</p></html>'
assert seen == ['request', 'response']
Đọc payload trong vòng lặp giúp bộ kiểm so trực tiếp byte nguồn. Nếu cần giữ nhiều record để xử lý sau, lưu dữ liệu cần thiết hoặc thiết kế cơ chế truy cập phù hợp. Đừng giữ một handle stream đã tiêu thụ rồi coi đó là bản sao payload độc lập.
Ví dụ đọc toàn body phù hợp với fixture nhỏ. Với tài liệu lớn, cần cách xử lý stream và giới hạn tài nguyên theo tác vụ. Không dùng một payload vài chục byte để dự báo bộ nhớ của cả kho lưu trữ.
lưu website dạng WARC và hai lớp metadata
WARC có header mô tả record, trong khi thông điệp HTTP bên trong cũng có header. Hai lớp có thể cùng dùng tên Content-Type hoặc Content-Length theo ý nghĩa khác nhau. Công cụ xuất cần giữ ranh giới để không gán nhầm giá trị.
Không trộn ContentLength của block và của body
Chiều dài block WARC không nhất thiết bằng chiều dài entity body HTTP vì block còn có cấu trúc thông điệp theo loại record. Khi kiểm, xác định đang đo lớp nào. Lấy số byte HTML để ghi đè mọi Content-Length sẽ làm hỏng metadata định dạng.
Tương tự, Content-Type của record HTTP không phải luôn là text/html. Body HTTP có thể là HTML nhưng record mô tả thông điệp HTTP được đóng gói. Đọc tài liệu của thư viện để biết API nào trả header WARC và API nào trả header HTTP.
Trong báo cáo lab, ghi riêng loại record, target URI, date và số byte payload đọc lại. Không cần sao chép mọi header vào một bảng duy nhất không có prefix. Các cột có tên theo lớp giúp người nhận hiểu ngay giá trị đến từ đâu.
Giữ timestamp theo sự kiện capture
Ngày trong record phản ánh sự kiện capture theo định dạng, không tự là ngày xuất bản nội dung. Một trang cũ được thu hôm nay có thể giữ ngày bài bên trong HTML và ngày capture khác nhau. Lưu cả hai nếu tác vụ cần, với tên rõ ràng.
Khi dùng fixture tự tạo, ghi rõ không có sự kiện HTTP live. Timestamp thể hiện thời điểm tạo record lab theo bộ kiểm, không phải bằng chứng website thật đã trả nội dung đó. Cách diễn đạt này tránh biến một tệp minh họa thành một chứng cứ ngoài đời không tồn tại.
Nếu thu thật, đồng hồ và cách ghi timestamp cần được quản lý theo yêu cầu dự án. Một chữ số thời gian dài không bảo đảm độ chính xác tương ứng. Ghi công cụ capture và điều kiện quan sát giúp đánh giá mức tin cậy của mốc thời gian.
lưu website dạng WARC với digest và kiểm toàn vẹn
Digest hỗ trợ đối chiếu byte theo phạm vi được định nghĩa. Payload digest và block digest không phải cùng một phép so trong mọi record. Cần giữ tên thuật toán và vùng dữ liệu được hash để kết luận có ý nghĩa.

Hai lớp header và digest
Trường kiểm |
Câu hỏi trả lời |
Giới hạn |
|---|---|---|
Hash tệp WARC |
Tệp lưu có đổi byte |
Không xác nhận nguồn đúng |
Block digest |
Block có khớp giá trị dự kiến |
Khác phạm vi payload |
Payload digest |
Payload có khớp |
Không chứng minh replay đủ |
Target URI và date |
Record gắn nguồn và lúc nào |
Cần tin quy trình capture |
Hash đúng không tự xác nhận sự thật nguồn
Một người có thể tạo WARC từ byte tự viết như lab này. Digest đúng chỉ xác nhận phép so trên dữ liệu đã ghi, không chứng minh một website ngoài Internet từng phát nó. Provenance cần gắn với quy trình thu và những bằng chứng phù hợp khác nếu dự án yêu cầu.
Với dữ liệu tự tạo, kết luận hợp lệ là payload đọc lại trùng byte đầu vào. Không dùng từ “chứng minh website đã có nội dung” cho ca này. Việc gọi đúng phạm vi giúp người đọc biết kiểm gì còn thiếu khi muốn lưu trữ nguồn thật.
Khi một công cụ tự giải nén hoặc dechunk trong API đọc, hash output của API có thể thuộc lớp khác raw byte lưu. Xác định ranh giới trước khi so với digest. Hai hash khác nhau không đủ kết luận tệp hỏng nếu chúng được tính trên hai biểu diễn khác nhau.
Giữ thuật toán và kiểm sau sao chép
Manifest tệp nên có thuật toán hash và giá trị đầy đủ, không chỉ một chuỗi rút gọn dùng làm nhãn giao diện. Khi chuyển kho hoặc đóng gói, kiểm lại tệp nhận được. Một tên archive không đổi không bảo đảm nội dung vẫn là bản đã nghiệm thu.
Digest bên trong record cũng cần được kiểm theo công cụ hỗ trợ, đặc biệt sau sửa hoặc tạo lại. Nếu chỉnh HTTP header, block có thể đổi dù body giữ nguyên. Đừng giữ digest cũ sau khi đã thay vùng dữ liệu mà nó mô tả.
Trong lab, thư viện tạo các trường digest và bộ kiểm so byte đọc lại. Bộ thử không đánh giá tính xác thực pháp lý hoặc một hệ thống ký chứng cứ. Nếu dự án cần những tính chất đó, phải có quy trình chuyên biệt ngoài bài hướng dẫn định dạng.
lưu website dạng WARC với scope và tài nguyên phụ
Một trang thường phụ thuộc CSS, ảnh, script và request dữ liệu. Lưu response HTML đầu tiên chưa đủ để replay mọi thứ như lúc xem bằng trình duyệt. Cần xác định phạm vi tài nguyên và tiêu chí đầy đủ theo mục tiêu lưu trữ.
Từ một response đến một bộ capture
Nếu mục tiêu chỉ là trích text từ HTML, một bộ response có thể đáp ứng phạm vi hẹp. Nếu mục tiêu là xem lại giao diện, cần kiểm tài nguyên và hành vi động. Đừng dùng cùng nhãn “đã lưu website” cho hai mức mà không giải thích.
Các request sinh sau JavaScript có thể không được crawler HTTP đơn giản thực hiện. Một WARC do crawler đó ghi vẫn hợp lệ về định dạng nhưng thiếu dữ liệu cho replay giao diện. Loại công cụ capture phải phù hợp với loại website và câu hỏi cần trả lời.
Tài liệu pywb cung cấp một nhánh công cụ replay để tham khảo. Bài này chưa chạy replay trình duyệt, nên không nhận bộ fixture một response là website phát lại đầy đủ. Giữ nhãn kiểm đọc byte tách với kiểm replay.
Không mở rộng scope theo mọi liên kết
Một seed lab có thể trỏ tới host ngoài scope. Bộ thu cần quy tắc chấp nhận theo host, đường dẫn và loại tài nguyên đã định. Có URL trong HTML không có nghĩa nhiệm vụ được phép tải nó hoặc cần giữ nó cho mục tiêu.
Robots và chính sách nguồn cần được xử lý theo công cụ, quyền và phạm vi dự án. Không dùng proxy để tiếp tục thu ngoài quyền hoặc qua một giới hạn nguồn đã đặt. WARC là định dạng lưu, không phải cơ chế cấp quyền truy cập.
Khi mua proxy cho tầng capture, kiểm tuyến và độ ổn định truyền riêng với chất lượng archive. Một tunnel hoạt động không xác nhận scope hoặc payload digest đúng. Bộ lab trong bài không kiểm gateway thương mại ProxyVN.
lưu website dạng WARC với dữ liệu nhạy cảm
Request có thể chứa Cookie, Authorization hoặc query có token; response có thể chứa dữ liệu theo tài khoản. Chính sách lưu cần xác định những gì được phép giữ. Đừng bật ghi mọi thông điệp vào một kho chia sẻ chỉ vì công cụ có tùy chọn capture.

Raw archive và bản xử lý
Quyết định trước khi ghi archive
Với nguồn riêng tư được cấp quyền, xác định người được đọc archive và thời hạn lưu theo yêu cầu dự án. Nếu cần lọc, ghi rõ phương pháp và tác động tới khả năng replay. Một bản đã loại thông tin không nên được nhận là bản nguyên gốc chưa biến đổi.
Nếu không cần dữ liệu tài khoản, dùng endpoint công khai được phép hoặc fixture tự tạo để kiểm. Lab trong bài không cần bất kỳ token nào. Điều này giúp chia sẻ gói tái hiện mà không vô tình mang theo phiên đăng nhập.
Giữ khóa riêng và bí mật công cụ ngoài ZIP bàn giao hướng dẫn. Tên target URI có thể vẫn chứa query nhạy cảm, nên báo cáo hiển thị cũng cần được kiểm theo chính sách. Không chỉ che header mà bỏ qua phần URL.
Phân biệt bản raw và bản đã xử lý
Nếu sửa archive để loại dữ liệu, tạo một bản đầu ra có nhãn rõ và giữ metadata quá trình theo chính sách. Không âm thầm sửa tệp đã nghiệm thu rồi giữ nguyên hash manifest. Mọi phép biến đổi ảnh hưởng vùng hash cần được phản ánh trong báo cáo.
Một bản xuất text từ WARC cũng là sản phẩm xử lý khác với record gốc. Giữ ID record và hash nguồn để truy lại. Không lấy text đã chuẩn hóa làm bằng chứng raw response giữ nguyên nếu dự án cần so byte.
Nếu archive bị từ chối vì dữ liệu ngoài phạm vi, ghi lý do và xử lý theo quy trình dự án. Không giữ thêm một bản bí mật chỉ để tiện kiểm. Provenance hữu ích phải nằm trong chính sách dữ liệu được phép, không vượt nó.
lưu website dạng WARC trong quản lý kho
Kho nhiều tệp cần chỉ mục, manifest và kiểm sao chép có hệ thống. Một thư mục đầy file .warc.gz không tự cho biết URL nào nằm ở đâu. Thiết kế tra cứu nên dựa trên nhu cầu đọc lại và công cụ đang dùng.
Chỉ mục là sản phẩm phụ có thể tạo lại
Chỉ mục giúp tìm record theo URL và thời gian, nhưng không thay payload archive. Nếu chỉ giữ chỉ mục rồi mất tệp gốc, không thể phục hồi body từ danh sách URL. Đây là ranh giới cần giữ khi so với API CDX ở một tác vụ khác.
Nếu chỉ mục được tạo lại, giữ version công cụ và cách ánh xạ tới tệp. Đổi tên hoặc di chuyển archive cần cập nhật tham chiếu phù hợp. Một record tìm thấy trong chỉ mục nhưng tệp đích không có là lỗi vận hành riêng với việc dữ liệu từng được thu.
Với nén, kiểm cách công cụ hỗ trợ truy cập record và offset. Không giả định một offset của tệp không nén dùng được nguyên vẹn trên tệp gzip. Chọn hệ sinh thái đọc ghi có kiểm thử tương thích theo nhu cầu dự án.
Đối soát số lượng theo loại record
Trong fixture cặp, số record là hai nhưng chỉ một record chứa response HTML mục tiêu. Nếu báo cả hai là hai trang đã lưu, số liệu sẽ sai đơn vị. Đếm request, response và loại khác riêng trước khi quy đổi thành số tài nguyên.
Một response lỗi vẫn là một response record có giá trị quan sát. Nó không phải trang mục tiêu thành công. Báo status HTTP cùng URL để phân biệt chất lượng thu thập với tính hợp lệ định dạng WARC.
Khi tệp có record tham chiếu như revisit, cách đếm payload cần theo công cụ và profile được hỗ trợ. Bài không tạo revisit nên không chứng nhận nhánh đó. Nếu dùng chống trùng archive, thêm ca đọc lại đủ dữ liệu trước khi giảm dung lượng theo cách ấy.
lưu website dạng WARC và ma trận nghiệm thu
Ma trận nghiệm thu nên có ba mức: tệp đọc được, payload đúng và tập capture đủ theo mục tiêu. Mỗi mức cần bằng chứng riêng. Một lượt đọc thành công không tự chứng nhận mức cuối.

Ba mức nghiệm thu archive
Ca đã chạy trên dữ liệu tự tạo
Bộ thử ghi request GET và response 200 với body biết trước, nối record và đọc lại tuần tự. Payload response phải bằng đúng byte nguồn. Target URI và date được lấy từ header record để kiểm metadata có mặt theo fixture.
Kiểm số record và loại theo thứ tự đã tạo giúp phát hiện tệp bị thiếu hoặc parser bỏ qua một phần. Với tệp thật, thứ tự có thể khác theo công cụ capture; kỳ vọng phải theo hợp đồng của bộ thử. Không áp thứ tự fixture cặp vào mọi archive ngoài dự án.
Ca này chưa gửi HTTP live, chưa lưu tài nguyên phụ và chưa chạy browser replay. Kết luận được giữ ở mức ghi đọc WARC có provenance lab. Những bước còn lại là ma trận cần bổ sung khi triển khai công cụ capture thật.
Ca nên thêm theo nhu cầu
Thêm một response khác body để kiểm manifest phát hiện thay đổi. Thêm tệp bị cắt có chủ đích để kiểm công cụ báo trạng thái không đủ. Không làm hỏng archive gốc của người dùng; tạo bản thử riêng trong thư mục lab.
Nếu cần replay, tạo site lab có HTML, CSS, ảnh và một tài nguyên ngoài scope, rồi kiểm cái được giữ và cái bị loại. Nếu cần dữ liệu động, thêm request do trình duyệt sinh theo thiết kế. Mỗi tài nguyên có expected output độc lập.
Tài liệu kho đặc tả IIPC giúp xác định version và profile liên quan. Khóa công cụ, cấu hình scope và bộ mẫu cùng báo cáo trước khi bàn giao. Giữ một phép kiểm nhỏ có thể chạy lại sẽ hữu ích khi nâng thư viện hoặc di chuyển kho.
lưu website dạng WARC từ HTTP loopback đã kiểm
Ngoài ví dụ tạo record bằng tay, bộ thử của đợt soạn còn dựng một origin loopback và capture một GET thật. Server trả body HTML tự tạo dài bốn mươi sáu byte. Khi đọc lại archive, payload response khớp đúng byte mà client đã nhận.
Tách phép thử live với phép tạo record
Ví dụ tạo record bằng tay dùng URL lab.invalid và WARC 1.1 được chỉ định. Phép capture HTTP dùng địa chỉ 127.0.0.1 với cổng do hệ điều hành cấp. Hai ca có mục tiêu khác nhau nên được ghi thành hai kết quả, không dùng một ca để gán thuộc tính chưa đo cho ca còn lại.
Origin loopback chỉ phục vụ dữ liệu của bộ thử. Client không dùng proxy môi trường trong ca direct này, và không có request tới website ngoài máy. Kết luận hợp lệ là hook HTTP đã ghi được cuộc trao đổi cục bộ vào archive rồi đọc lại đúng payload.
Ca đó vẫn không kiểm browser replay hoặc tài nguyên phụ. Một GET đơn không tạo CSS, ảnh hay request JavaScript nếu chúng không tồn tại trong fixture. Người dùng cần giữ mục tiêu capture và mục tiêu xem lại giao diện riêng trong biên bản.
Thứ tự import ảnh hưởng hook capture
Trong môi trường đã thử, module capture cần được nạp trước Requests để hook được đường HTTP liên quan. Khi import theo thứ tự không phù hợp, request vẫn thành công nhưng archive không có cặp record mong đợi. Assertion số record đã bắt lỗi này thay vì để một tệp được tạo rỗng đi qua nghiệm thu.
Sau khi sửa thứ tự import và chạy tiến trình mới, archive có response và request cho đúng URL loopback. Điều này minh họa vì sao “request thành công” và “capture thành công” cần hai assertion. Một công cụ làm việc tốt ở tầng client chưa chứng minh bộ ghi đã nhìn thấy thông điệp.
Đoạn capture ngắn dưới cần origin lab đã được dựng và URL được thay bằng địa chỉ thực của nó. Session tắt đọc proxy môi trường để giữ ca direct có kiểm soát. Nếu muốn kiểm qua proxy, đó là một ca khác có log tuyến và điều kiện tương ứng.
from warcio.capture_http import capture_http
import requests
with capture_http('capture.warc.gz'):
with requests.Session() as session:
session.trust_env = False
response = session.get('http://127.0.0.1:8788/page', timeout=5)
response.raise_for_status()
Không đổi cấu hình proxy hệ thống để làm ca này direct. Lựa chọn được giữ trong session thử và hết hiệu lực khi session đóng. Cách cô lập giúp người nhận chạy lại mà không ảnh hưởng các công việc khác trên máy.
Kiểm version thực của archive
Trong phép capture dùng mặc định của API đã thử, record đọc lại có nhãn WARC/1.0. Ví dụ writer bằng tay đã chọn WARC/1.1. Việc cùng dùng warcio không có nghĩa mọi API đều phát cùng version mà người viết đang muốn nói.
Vì vậy biên bản nên đọc version từ output thay vì chỉ ghi phiên bản mong đợi trong cấu hình. Nếu dự án yêu cầu 1.1, chọn API và tham số được thư viện hỗ trợ rồi chạy lại ca kiểm. Không sửa dòng đầu tệp bằng text editor để ép nhãn mà không xét cấu trúc liên quan.
Đầu ra capture còn ghi response trước request trong ca đã quan sát, khác thứ tự ví dụ tạo tay. Bộ kiểm capture so tập loại record và quan hệ nguồn, không ép thứ tự của một cách tạo khác. Thứ tự record cần được hiểu theo công cụ, không suy từ thứ tự dòng code ở client.
Đối soát cả bốn dấu vết
Phép thử live có bốn dấu vết cần nối: URL client gọi, body client nhận, record target URI và payload đọc lại. Chúng cùng trỏ tới dữ liệu loopback đã định. Chỉ kiểm một trong bốn sẽ bỏ sót trường hợp capture nhầm URL hoặc reader trả dữ liệu khác.
Request record của GET không có body là điều phù hợp với fixture này. Không yêu cầu mọi record đều có payload HTML để được tính hợp lệ. Ngược lại, response record cần body đúng bốn mươi sáu byte và hash đọc lại phù hợp với nguồn tự tạo.
Sau test, origin được đóng và archive chỉ nằm trong thư mục QA riêng. Gói bài Word không cần chứa khóa, binary hoặc server đang chạy. Giữ báo cáo kết quả là đủ để người biên tập biết phần HTTP loopback nào đã kiểm và phần replay nào còn cần bổ sung.
Hai lần capture có thể tạo tệp WARC khác hash do timestamp và ID record đổi, dù payload HTML giống nhau. Khi so nội dung, dùng phép kiểm payload ở cùng tầng. Khi kiểm sao chép một archive cụ thể, dùng hash toàn tệp của đúng bản đã bàn giao.
Không dùng sự khác nhau của hash archive qua hai lần chạy để kết luận nguồn đã sửa bài. Trước tiên so target, thời điểm và payload; những trường metadata được tạo mới là thay đổi dự kiến của một lần capture mới.
WARC giữ record có cấu trúc; payload đúng và replay đầy đủ là hai mức kiểm khác nhau cần được ghi riêng.
Anh em hãy lưu dữ liệu mẫu cùng cấu hình và kết quả đối chiếu để lần cập nhật sau có cơ sở kiểm lại. Tham khảo thêm tại Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam. Bắt đầu từ phạm vi nhỏ và tiêu chí rõ ràng khi triển khai lưu website dạng WARC.