Nội dung
Đây là ghi chép của một lần dọn nội dung trùng trên marketing365.vn. Không phải trùng giữa bài này với bài kia — mà trùng ngay bên trong cùng một bài: người đọc kéo xuống, gặp lại đúng cái tiêu đề mục vừa đọc, rồi đọc lại đúng đoạn văn vừa đọc. Có bài lặp tới năm lượt.
Bài này ghi lại ba thứ: cách tôi tìm ra, một mốc đo sai làm tôi suýt kết luận “không có bài nào cần gỡ”, và con số sau khi cắt. Kèm phần cuối không vui: ba ngày sau đợt dọn, bệnh quay lại.

Dấu hiệu đầu tiên: một bài dài gấp đôi bình thường
Tôi không đi tìm lỗi này. Tôi đang sắp xếp lại nội dung theo chủ đề, có liệt kê bài theo độ dài để xem bài nào đáng tách đôi. Bài dài nhất ra 79.123 ký tự trong thân bài. Bài dài nhì hơn 56.000. Trong khi bài viết bình thường của site nằm quanh 8.000 đến 20.000.
Mở bài 79.123 ký tự ra đọc thì thấy ngay: phần “Câu hỏi thường gặp” xuất hiện năm lần, mỗi lần y hệt nhau. Mở bài 56.000 ký tự thì thấy nửa sau của bài đúng bằng nửa trước, chép lại từ đầu.
Một bài thì còn gọi là tai nạn. Hai bài liền nhau, cùng một kiểu, thì phải quét cả site. Vấn đề là quét bằng cách nào cho ra số đúng.
Cách tìm: cắt bài theo tiêu đề mục rồi băm từng đoạn
Cách ngây thơ là tìm chuỗi giống nhau trong bài. Cách này hỏng ngay, vì hai đoạn “trùng” thường không giống nhau từng ký tự: chỗ thì lệch một dấu cách, chỗ thì tên ảnh khác nhau đúng một chữ số.
Cách chạy được là cắt thân bài tại mọi tiêu đề mục, chuẩn hoá từng đoạn rồi băm nó ra một mã ngắn. Hai đoạn cùng mã băm nghĩa là cùng nội dung, dù chúng cách nhau ba chục nghìn ký tự.
# cắt thân bài tại mọi tiêu đề mục (h2 và h3), không chỉ h2
$parts = preg_split('/(?=<h[23][ >])/i', $content);
# mỗi đoạn: bỏ thẻ, dồn khoảng trắng, rồi băm
foreach ($parts as $p) {
$plain = preg_replace('/\s+/u', ' ', wp_strip_all_tags($p));
$hash[] = md5(trim($plain));
}
# mã băm nào xuất hiện từ 2 lần trở lên = đoạn bị chép lại
Chạy trên toàn bộ bài đã đăng, kết quả ra 43 bài có tiêu đề mục lặp trong chính nó. Trong đó bốn bài lặp nguyên khối nội dung, 39 bài còn lại là bài giải nghĩa thuật ngữ và chỉ dư đúng một thứ: cái nhãn “Câu hỏi thường gặp” thứ hai, bên dưới không có chữ nào.
Mã băm của các đoạn lặp khớp nhau 100%. Nghĩa là chúng được chép lại thật, chứ không phải viết lại theo cùng một dàn ý — hai chuyện rất khác nhau khi đi tìm nguyên nhân.
Mốc đo lệch một chữ, kết quả ra ngay “gỡ 0 bài”
Với 39 bài giải nghĩa, tôi cần trả lời một câu đơn giản: bên dưới cái nhãn thừa đó có nội dung không? Có thì phải đọc từng bài. Không có thì chỉ gỡ nhãn, an toàn, làm hàng loạt được.
Lần chạy đầu tiên trả về:
SẼ GỠ: 0 bài | bỏ qua: 40
Đọc con số này thì có hai cách hiểu. Cách dễ chịu: bên dưới nhãn nào cũng có nội dung, vậy không có gì để gỡ, xong việc. Cách khó chịu: đoạn lệnh của tôi đang đo sai.
Sai thật. Tôi đo phần thân bên dưới nhãn bằng cách cắt tới thẻ <h2> kế tiếp. Nhưng bên dưới cái nhãn thừa ấy là một loạt thẻ <h3> của mục khác. Mốc dừng bị đẩy đi xa, đoạn đo dài ra, và bài nào cũng trông như “có nội dung”. Đổi mốc dừng thành tiêu đề bất kỳ, cùng bộ dữ liệu, cùng đoạn lệnh, chỉ khác một chữ trong mẫu tìm:
SẼ GỠ: 40 bài | bỏ qua: 0
Đây là kiểu sai khó chịu nhất, vì nó không báo lỗi. Lệnh chạy trơn tru, in ra một con số gọn gàng, và con số đó đảo ngược quyết định. Nếu tôi tin lần chạy đầu, 40 bài sẽ vẫn còn nguyên cái nhãn rỗng đến hôm nay.
Từ vụ này tôi thêm một thói quen: mỗi khi một phép đo trả về đúng 0 hoặc đúng 100%, tôi coi đó là dấu hiệu đáng ngờ chứ không phải kết quả. Số tròn quá thường là dấu hiệu mốc đo đặt sai chỗ.
Trước khi cắt phải soát ảnh, không thì mất ảnh
Với bốn bài lặp nguyên khối, việc cắt nguy hiểm hơn nhiều. Bản chép lại không phải bản sao sạch: có bản đã bị chèn thêm link nội bộ, có bản dùng file ảnh khác — cùng một ảnh nhưng tên file lệch nhau đúng một chữ số ở cuối, kiểu -89.jpeg và -89-1.jpeg.
Nghĩa là nếu cứ giữ khối đầu và cắt các khối sau, có khả năng cắt luôn tấm ảnh chỉ tồn tại ở khối cuối. Nên bước bắt buộc trước khi cắt là liệt kê tên file ảnh trong từng khối, đối chiếu, và chỉ cắt phần không chứa ảnh riêng. Chỗ nào ảnh riêng nằm trong khối sẽ bị cắt thì kéo ảnh về khối giữ lại trước, cắt sau.
Chuyện link cũng vậy. Bốn bài này nằm trong đợt tôi từng gắn link tự động hỏng — chuyện đó tôi kể riêng ở bài 412 bài bị gắn link lạc đề, và con số 479 tôi báo sai. Cắt khối chứa link mà không kiểm tra thì bài mất link, và lần đếm link sau đó lại ra một con số sai nữa.
Số sau khi cắt

- Bài lặp khối hỏi đáp năm lần: 79.123 xuống 42.051 ký tự.
- Bài có nửa sau y hệt nửa trước: 56.089 xuống 30.488.
- Hai bài lặp vài mục giữa bài: 53.058 xuống 41.068 và 30.367 xuống 26.118.
- 39 bài giải nghĩa: chỉ gỡ nhãn rỗng, không mất chữ nào.
Một chi tiết nhỏ nhưng nên nói rõ: đo lại hôm nay, bốn bài đó ra 42.027, 30.365, 41.014 và 26.098 — lệch vài chục ký tự so với con số ghi trong nhật ký hôm cắt. Đây là do bài được sửa tiếp sau đợt dọn, không phải cắt hụt. Tôi để cả hai cột trong ảnh thay vì chỉ giữ cột nào đẹp hơn.
Còn một thứ tôi không làm được: truy ra nguyên nhân. Bốn bài đó do quy trình tự động sinh, và tôi không tìm lại được đúng lần chạy nào đã ghép nội dung nhiều lượt vào một bài. Lúc đó tôi tự nhủ dọn xong là ổn.
Ba ngày sau, bệnh quay lại
Hôm nay 14/08/2026, trước khi viết bài này, tôi chạy lại đúng đoạn lệnh cũ trên 1.633 bài đã đăng để kiểm chứng các con số. Nhóm 43 bài cũ sạch, không bài nào lặp lại. Nhưng danh sách trả về một bài mới.
Bài Cách tối ưu internal link cho website, đăng ngày 12/08/2026 — tức ba ngày sau đợt dọn. Nó có 22 tiêu đề mục, trong đó 7 tiêu đề lặp lại, thân bài dài 99.939 ký tự và lặp khoảng ba lượt. Dài hơn cả bài nặng nhất của đợt trước.
Tôi không tự cắt nó. Ba bản chép trong bài không giống hệt nhau — mã băm của chúng khác nhau, do có bản đã bị chèn link nội bộ còn bản kia thì chưa. Cắt bản nào giữ bản nào là một quyết định về nội dung, không phải thao tác máy móc, nên việc đó tôi báo lại để người phụ trách quyết. Ghi ra đây vì đó là tình trạng thật của site lúc bài này lên lịch.
Bốn thứ tôi mang đi khỏi vụ này:
- Đo bằng mã băm từng đoạn, đừng đo bằng cách so chuỗi. Hai đoạn chép lại hiếm khi giống nhau từng ký tự.
- Mốc dừng của phép cắt quan trọng ngang nội dung phép cắt. Lệch từ “tiêu đề cấp 2” sang “tiêu đề bất kỳ” là lệch từ 0 bài sang 40 bài.
- Kết quả tròn trịa quá thì kiểm lại phép đo trước khi mừng.
- Dọn xong mà không tìm ra nguyên nhân thì chỉ là dọn, không phải sửa. Ba ngày sau nó quay lại, và lần này bài nặng hơn.
Số trong bài này đo trên marketing365.vn, cụ thể ngày nào thì ghi ngay cạnh số. Ai muốn kiểm chứng thì mở hai bài dài nhất ra đọc là thấy — phần đã cắt thì không còn, còn bài 12/08 thì vẫn đang lặp.



