Thu thập dữ liệu web cho nghiên cứu cần qua bốn bước trước khi viết dòng mã đầu tiên: tìm xem có API chính thức không, đọc điều khoản sử dụng, đọc tệp robots.txt, và xác định dữ liệu có chứa thông tin cá nhân hay không. Khi đã thu, giãn tốc độ, tự giới thiệu, và lưu ngày giờ thu thập.
Thư viện Python làm việc thu thập rất dễ: vài dòng requests là tải được trang. Chính vì dễ nên rắc rối thường đến từ phía không kỹ thuật: máy chủ bị gửi quá nhiều yêu cầu, điều khoản bị vi phạm, dữ liệu cá nhân bị lưu không có căn cứ, hội đồng đạo đức hỏi lại khi bài sắp nộp. Bài này đi theo thứ tự nên làm.
Có API chính thức thì dùng API
Vì sao ưu tiên API
API là cửa mà chủ dữ liệu mở ra cho việc truy cập tự động: có điều khoản rõ, có giới hạn tốc độ công bố, dữ liệu trả về có cấu trúc, ít hỏng khi trang đổi giao diện. Nhiều nguồn dữ liệu học thuật có API công khai, như Crossref, OpenAlex, các kho lưu trữ dùng giao thức OAI-PMH. Nhiều cơ quan thống kê và cổng dữ liệu mở cũng cho tải trực tiếp.
Đọc tài liệu API trước
Tìm ba thông tin: có cần đăng ký khoá không, giới hạn bao nhiêu yêu cầu trong một khoảng thời gian, và điều khoản về việc lưu trữ, chia sẻ lại dữ liệu. Một số API đề nghị bạn ghi địa chỉ thư liên hệ trong yêu cầu để được xếp vào nhóm ưu tiên; làm theo, vì chủ dữ liệu cần liên lạc được với bạn khi có sự cố.
Đọc điều khoản và robots.txt
Điều khoản sử dụng của trang có thể cấm thu thập tự động, cấm dùng cho mục đích thương mại, hoặc cho phép với điều kiện. Đọc và lưu lại bản điều khoản tại thời điểm bạn thu, kèm ngày. Nếu điều khoản cấm hoặc không rõ, gửi thư hỏi chủ trang, nói rõ mục đích nghiên cứu, phạm vi và cách lưu trữ; nhiều đơn vị sẵn lòng cấp quyền hoặc gửi bộ dữ liệu.
Tệp robots.txt nằm ở gốc mỗi tên miền, cho biết đường dẫn nào chủ trang không muốn máy tự động truy cập, đôi khi kèm Crawl-delay là số giây nên chờ giữa hai yêu cầu. Đây là quy ước kỹ thuật, không thay được điều khoản, nhưng tôn trọng nó là mức tối thiểu. Python có sẵn bộ đọc: from urllib import robotparser, rp = robotparser.RobotFileParser(), rp.set_url(goc + '/robots.txt'), rp.read(), rồi rp.can_fetch(ten_bot, duong_dan) trả True hoặc False, và rp.crawl_delay(ten_bot) trả số giây nếu tệp có khai.
Giãn tốc độ và tự giới thiệu
Một kịch bản thu thập cư xử đúng mực có những thành phần sau:
| Thành phần | Cách làm trong Python | Vì sao |
|---|---|---|
| Tên bot và liên hệ | headers={'User-Agent': 'ten-de-tai (thu liên hệ của nhóm)'} | Chủ trang biết ai đang truy cập và liên lạc được |
| Giãn cách | time.sleep() giữa hai yêu cầu, không nhỏ hơn Crawl-delay nếu có | Không làm chậm máy chủ của người khác |
| Hết giờ chờ | requests.get(url, headers=headers, timeout=30) | Kịch bản không treo vô hạn |
| Xử lý mã 429, 503 | Dừng, đọc tiêu đề Retry-After nếu có, chờ lâu hơn rồi mới thử lại | Máy chủ đang báo quá tải hoặc bạn đang gửi quá nhanh |
| Một luồng | Không chạy song song nhiều yêu cầu tới cùng một trang | Song song là cách nhanh nhất để bị chặn |
| Lưu trang gốc | Ghi HTML thô ra tệp trước khi tách dữ liệu | Sửa bộ tách không phải tải lại |
Chạy thử trên vài chục trang, kiểm dữ liệu tách ra, rồi mới chạy toàn bộ. Ước lượng tổng thời gian trước: một vạn trang với giãn cách năm giây là gần mười bốn giờ, nên lên lịch chạy giờ thấp điểm và chia đợt.
Một kịch bản mẫu từ đầu tới cuối
Khung dưới đây ghép các phần trên; thay tên biến theo đề tài của bạn:
- Đọc danh sách đường dẫn cần thu từ một tệp CSV, kèm cột trạng thái để biết đường dẫn nào đã xong.
- Đọc robots.txt một lần, bỏ khỏi danh sách các đường dẫn mà
rp.can_fetch()trảFalse, ghi lại số bị bỏ. - Lặp qua từng đường dẫn chưa xong: gửi yêu cầu với tiêu đề tự giới thiệu và
timeout; nếu mã trả về là 200, ghi HTML thô ra tệp mang mã định danh của trang; ghi một dòng nhật ký gồm đường dẫn, thời điểm, mã trả về. - Gặp 429 hoặc 503 thì dừng lâu hơn rồi thử lại, tối đa vài lần; gặp 404 thì ghi nhận rồi bỏ qua.
- Ngủ theo giãn cách đã chọn trước yêu cầu tiếp theo.
- Kịch bản tách dữ liệu chạy riêng, đọc các tệp HTML đã lưu, ghi ra bảng.
Tách hai việc tải và tách dữ liệu ra hai kịch bản là quyết định quan trọng nhất. Kịch bản tải chạy chậm, có thể dừng giữa chừng và chạy tiếp nhờ cột trạng thái. Kịch bản tách chạy nhanh, sửa và chạy lại bao nhiêu lần cũng được mà không gửi thêm yêu cầu nào tới máy chủ của người khác.
Để tách dữ liệu từ HTML, thư viện BeautifulSoup (gói beautifulsoup4) với phương thức select() theo bộ chọn CSS là đủ cho phần lớn trang. Viết bộ tách sao cho trả về giá trị rỗng và ghi cảnh báo khi không tìm thấy phần tử, thay vì dừng cả chương trình vì một trang có cấu trúc khác.
Lưu ngày thu thập và nguồn gốc
Trang web thay đổi liên tục; bài báo của bạn mô tả dữ liệu tại một thời điểm. Mỗi bản ghi nên có ít nhất địa chỉ trang, ngày giờ tải (theo giờ chuẩn, ghi múi giờ) và mã trạng thái trả về. Lưu HTML thô thành tệp nén theo đợt, đặt tên có ngày. Trong phần phương pháp, ghi rõ khoảng thời gian thu, phạm vi trang, tiêu chí chọn, số trang thất bại.
Một tình huống hay gặp: phản biện yêu cầu bổ sung một biến, ví dụ số bình luận, mà bộ tách ban đầu không lấy. Nếu đã lưu HTML thô, bạn chỉ cần sửa bộ tách và chạy lại trên tệp đã lưu. Nếu không, phải thu lại, và dữ liệu mới đã khác dữ liệu cũ.
Dữ liệu cá nhân và hội đồng đạo đức
Dữ liệu công khai vẫn có thể là dữ liệu cá nhân
Tên người dùng, ảnh đại diện, bình luận, địa điểm đăng bài trên mạng xã hội đều có thể nhận diện một người. Việc chúng hiện công khai không có nghĩa người viết đồng ý cho nghiên cứu thu thập, lưu trữ và phân tích. Ở Việt Nam, Luật Bảo vệ dữ liệu cá nhân có hiệu lực từ ngày 1/1/2026 và các văn bản hướng dẫn là khung pháp lý cần đối chiếu; trường hoặc viện của bạn có thể có quy định riêng.
Làm gì trước khi thu
Hỏi hội đồng đạo đức của cơ sở xem đề tài cần xét duyệt ở mức nào. Chuẩn bị sẵn: dữ liệu gì, lấy từ đâu, có lấy thông tin nhận diện không, lưu ở đâu, ai được truy cập, giữ bao lâu, ẩn danh thế nào, trích dẫn nguyên văn bình luận trong bài có làm lộ người viết không.
Thu tối thiểu
Chỉ lấy trường cần cho câu hỏi nghiên cứu. Không cần tên người dùng thì thay bằng mã băm ngay lúc thu, không lưu bản gốc. Không cần ảnh thì không tải ảnh.
Lỗi hay gặp và việc nên làm trước khi bắt đầu
Những sai lầm làm hỏng một đề tài dùng dữ liệu web:
- Chạy song song hàng chục luồng để “cho nhanh”, bị chặn địa chỉ IP của cả trường.
- Không lưu ngày thu và trang gốc, không trả lời được câu hỏi của phản biện về thời điểm dữ liệu.
- Đưa bộ dữ liệu thô có tên người dùng lên kho dữ liệu mở kèm bài báo.
- Dựa vào việc trang không chặn để coi như được phép.
- Việc nên làm ngay: viết một trang mô tả kế hoạch thu thập gồm nguồn, điều khoản, robots.txt, tốc độ, trường dữ liệu, nơi lưu, rồi gửi người hướng dẫn và hội đồng đạo đức trước khi chạy.
Câu hỏi thường gặp
robots.txt có giá trị pháp lý không?
robots.txt là quy ước kỹ thuật, không phải hợp đồng. Giá trị pháp lý nằm ở điều khoản sử dụng và luật hiện hành. Tuy vậy, bỏ qua robots.txt là dấu hiệu thiếu thiện chí, nhất là khi có tranh chấp.
Thu thập để nghiên cứu phi thương mại thì có được miễn không?
Mục đích nghiên cứu không tự động miễn trừ nghĩa vụ về điều khoản, bản quyền hay dữ liệu cá nhân. Hỏi bộ phận pháp chế hoặc hội đồng đạo đức của cơ sở khi chưa rõ.
Có được chia sẻ bộ dữ liệu đã thu kèm bài báo không?
Tuỳ điều khoản nguồn và bản chất dữ liệu. Nhiều trường hợp chỉ chia sẻ được danh sách mã định danh hoặc đường dẫn kèm mã thu thập, không chia sẻ nội dung. Dữ liệu có thông tin cá nhân cần ẩn danh trước.
Trang hiển thị bằng JavaScript thì thu thế nào?
Trước hết mở công cụ dành cho nhà phát triển trong trình duyệt, xem trang có lấy dữ liệu từ một điểm truy cập JSON không. Nếu không, có thể dùng trình duyệt tự động như Playwright, nhưng tốn tài nguyên hơn, càng phải giãn tốc độ.
Nên giãn cách bao nhiêu giây?
Theo Crawl-delay nếu robots.txt có khai, theo giới hạn công bố nếu là API. Nếu không có hướng dẫn, chọn khoảng vài giây giữa hai yêu cầu và theo dõi thời gian phản hồi của máy chủ, chậm lại khi thấy phản hồi chậm dần.