Đánh giá Scrapy 2.17: Bỏ qua trình duyệt và gọi thẳng API

Cập nhật lần cuối vào July 17, 2026
Đánh giá Scrapy 2.17: Bỏ qua trình duyệt và gọi thẳng API
Tóm tắt bằng AI
This Scrapy review challenges the common claim that the framework is outdated because it does not run JavaScript. The tests show that Scrapy is strongest when it can replay the underlying HTTP or JSON API behind a page, producing clean structured output without browser overhead. The article covers static extraction, API-backed dynamic data, error handling, feed exports, setup cost, and the point where browser rendering becomes necessary. It presents Scrapy as a mature, production-shaped crawler for HTTP-first scraping, queues, pipelines, and exports, rather than a drop-in solution for every JavaScript-rendered page.

Scrapy thường bị xếp vào nhóm "không xử lý được website hiện đại" chỉ vì nó không chạy JavaScript. Nhưng nhìn như vậy là ngược hoàn toàn với bản chất của nó. Không render trang mới chính là ý tưởng cốt lõi, và khi bạn thấy nó vận hành thực tế, bạn sẽ không còn xem đó là một thiếu sót nữa.

Tôi đã tự kiểm chứng điều này chỉ trong một lần chạy. Tôi dựng một trang catalog được render bằng JavaScript, trỏ Scrapy vào giao diện mà trình duyệt sẽ hiển thị, và kết quả là chỉ kéo về 0 thẻ sản phẩm. Sau đó, tôi đưa cùng con spider đó đến endpoint JSON mà trang này âm thầm gọi ở nền, và nhận lại 8/8 mục dữ liệu, gọn ghẽ. Cùng một công cụ, cùng một phiên làm việc, nhưng hai kết quả đối lập — và chính khoảng cách giữa hai con số đó là trọng tâm của bài đánh giá này.

Scrapy thực sự là gì, và không phải là gì

Scrapy HTTP-only workflow

Scrapy là một framework Python dùng để thu thập dữ liệu từ website và trích xuất dữ liệu có cấu trúc. Đó cũng chính là cách mà nhóm phát triển mô tả trong tài liệu tổng quan, và sau khi sử dụng, tôi thấy mô tả đó rất chuẩn — không hề cần phải tô vẽ thêm. Đây là dự án đủ lâu đời và đủ phổ biến để trở thành câu trả lời phản xạ khi một lập trình viên Python hỏi dân làm nghề thường dùng gì để scrape dữ liệu, và các con số trên repo cũng xác nhận điều đó: khoảng 62,981 sao GitHub tính đến 2026-07-07 (scrapy/scrapy), cùng 11,773 lượt fork và 590 issue đang mở trong cùng ngày. Dự án dùng giấy phép BSD-3-Clause, yêu cầu Python 3.10 trở lên, và phiên bản tôi đem ra thử là 2.17.0 — đúng ngày tôi chạy kiểm thử thì bản này vừa được phát hành buổi sáng, nên ở đây không có chuyện “đã cũ quá lâu” để phải trừ điểm.

Đây là điểm phân tách Scrapy với làn sóng AI crawler mới hơn: mặc định, Scrapy chỉ làm việc qua HTTP. Không có trình duyệt. Không có engine render. Nó kéo HTML về qua mạng, chuyển cho bộ phân tích, rồi để bạn lấy trường dữ liệu bằng CSS selector hoặc XPath. Gọi đó là một hạn chế thì cũng đúng một nửa, nhưng lại bỏ sót hoàn toàn triết lý thiết kế. Giả định của Scrapy là: mở một trình duyệt Chrome không đầu chỉ để scrape một tác vụ thông thường thường là cách làm sai; cách thông minh hơn là tìm đúng request dữ liệu mà trang đã gọi sẵn rồi đánh thẳng vào đó.

Đây không phải là tôi tự gán ý tưởng này cho công cụ. Tài liệu chính thức về nội dung động nói rất rõ: hãy tìm và mô phỏng request dữ liệu nền trước, và chỉ dùng headless browser như phương án cuối khi việc tái tạo request đó là không khả thi. Phần lớn scraper sẽ mở trình duyệt trước rồi mới nghĩ đến API. Scrapy thì đảo ngược mặc định đó.

Các tính năng chính, và lựa chọn thiết kế đứng sau từng phần

Nhìn bên trong, Scrapy là một tập hợp nhiều thành phần, và mỗi thành phần đều ngầm giả định một điều về bạn: bạn là một developer muốn kiểm soát, không phải người tìm một nút bấm duy nhất để xong việc.

Spiders. Bạn viết một class, cung cấp danh sách URL khởi đầu, rồi định nghĩa callback parse để trả về item hoặc tiếp tục lần theo các liên kết khác. Điều này nhiều dòng hơn so với các công cụ trích xuất no-code — tức là bạn tự viết quy tắc lấy dữ liệu — nhưng bù lại, bạn có quyền kiểm soát chính xác dữ liệu nào được lấy và crawl đi đâu tiếp theo.

Selectors. Phần phân tích dữ liệu dựa trên parsel, mà bên dưới là lxml. CSS và XPath đều được xem như tính năng chính chứ không phải thứ gắn thêm cho có. Chính nền tảng lxml giúp việc chọn dữ liệu nhanh và khiến code trích xuất đọc lên giống như ý định của bạn, chứ không phải một mớ cắt chuỗi rối rắm.

Feed exports. Chỉ cần trỏ spider vào một file, Scrapy sẽ tự xuất item ra JSON, JSON Lines, CSV hoặc XML mà không cần bạn viết thêm cơ chế xuất dữ liệu. Trong lần chạy của tôi, một spider trên catalog tĩnh đã xuất ra cả JSON lẫn CSV mà tôi không phải viết một dòng code export nào — câu chuyện về feed export là có thật, và nó làm đúng như mô tả.

AutoThrottle và kiểm soát crawl. Request được lập lịch bất đồng bộ trên Twisted, và bạn có thể dùng giới hạn concurrency, độ trễ tải, giới hạn độ sâu, AutoThrottle để tự điều chỉnh tốc độ, cùng việc tuân thủ robots.txt. Đây là những cơ chế giúp một crawl lớn không biến thành một vụ “đập” quá tải lên server.

Chỉ HTTP, nhưng như một tính năng. Không có browser đồng nghĩa với ít tốn RAM hơn, throughput cao hơn, và không phải chăm sóc một rendering engine — miễn là dữ liệu bạn cần có thể lấy qua HTTP thuần. Và thực tế thì, thường xuyên hơn nhóm thích browser-first vẫn nghĩ, đúng là như vậy.

Cài đặt: đống phụ thuộc mà chẳng ai thường chụp màn hình

Scrapy dependency stack

Việc cài đặt diễn ra khá êm, điều này với một framework cỡ này thì đáng để nói thẳng. pip install Scrapy==2.17.0 chạy trơn tru trong một virtual environment mới trên macOS arm64, kéo về các binary wheel và không có gì phải biên dịch rồi kẹt giữa chừng. Không có drama nào để kể — và đó chính là điều tốt.

Nhưng hãy nhìn kỹ thứ được kéo về. Lệnh scrapy version -v báo Scrapy 2.17.0 đang chạy trên lxml 6.1.1, Twisted 26.4.0, pyOpenSSL 26.3.0 và cryptography 49.0.0, cùng với parsel, cssselecttldextract. Đây là một footprint thật sự — cả một bộ khung crawl chứ không phải một file HTML parser đơn lẻ. Trên máy của tôi, mọi thứ đều có wheel sẵn nên cài đặt rất nhẹ nhàng. Nhưng trên các môi trường khác, tài liệu chính thức vẫn cảnh báo rằng có thể phát sinh vấn đề phụ thuộc theo nền tảng, và trong thực tế thì phần hay vướng nhất thường nằm ở cryptographyTwisted, nên nếu bạn dùng hệ thống hơi đặc thù thì hãy chừa thời gian cho khâu này. Ở đây cài đặt rất mượt; tuy vậy, kích thước của những gì được cài lên máy vẫn là điều đáng biết trước khi bạn quyết định, vì bạn đang kéo về cả một framework và nó nặng đúng như một framework.

Thử thực tế: phần nào hoạt động tốt

Scrapy hands-on results

Khi đã cài xong, đường xử lý tĩnh hoạt động rất sạch. Thu hồi đầy đủ, không rơi mất gì.

Kiểm thửKết quảThời gian chạy
Catalog tĩnh nội bộ + phân trang12/12 sản phẩm0.557s
Xuất CSV cho catalog tĩnhGhi ra 12 dòng(cùng lần chạy)
Trích xuất bài viếttiêu đề + 3/3 đoạn nội dung0.416s
Crawl graph, DEPTH_LIMIT=211 trang ở các độ sâu 0/1/20.904s
Trang lỗi 500 nội bộghi nhận status 500, không bị crash0.424s
Books to Scrape (công khai)20 sản phẩm2.053s
Quotes to Scrape spider (công khai)12 quote items3.465s

Spider trên catalog tĩnh đi qua phân trang từ trang một sang trang hai và lấy đủ 12/12 bản ghi dự kiến, rồi xuất ra cả JSON lẫn CSV chỉ trong cùng một lượt. Fixture bài viết mới là phần đáng chú ý nhất. Scrapy không tự cố “làm sạch” trang thành Markdown gọn gàng — thay vào đó, tôi chủ động nhắm vào các trường article bằng selector cụ thể và tách text điều hướng, footer ra thành trường riêng, nhờ vậy tôi lấy được 3/3 đoạn nội dung chính còn phần boilerplate được giữ riêng chứ không bị trộn lẫn vào kết quả. Đây chính là cái giá phải trả: bạn tự viết selector, và đổi lại bạn nhận đúng thứ mình muốn, không hơn không kém.

Kiểm soát crawl ở quy mô nhỏ cho kết quả ổn. Với DEPTH_LIMIT=2, độ trễ tải ngắn, giới hạn concurrency theo domain, và bật robots.txt, đồ thị crawl ghi nhận 11 trang ở các độ sâu 0, 1 và 2, và việc đếm độ sâu diễn ra đúng như mong đợi. Xử lý lỗi cũng bình thản không kém. Trang 500 có chủ đích được trả về như một item có cấu trúc với status 500 thông qua handle_httpstatus_list — không exception, không làm dừng toàn bộ tiến trình. Scrapy xem một mã lỗi là thứ bạn xử lý ngay trong logic spider, thay vì một cú sốc làm sập luôn cả crawl.

Thử thực tế: bức tường JavaScript và cánh cửa nằm bên cạnh

Scrapy JS page 0 nodes vs JSON API 8/8

Đây là kết quả mà bài đánh giá này xoay quanh.

Tôi trỏ HTTP fetcher của Scrapy vào một fixture catalog được render bằng JavaScript. Nó tải HTML nguồn, thấy 0 node .product-card, rồi bỏ qua — vì nó không chạy script vốn sẽ vẽ ra những card đó. Trang public Quotes to Scrape JS page cũng cho ra cùng một kết luận: 0 node quote được render. Nếu dừng bài test ở đây, bạn có thể sẽ kết luận Scrapy không phù hợp với bất kỳ thứ gì được xây dựng trong thập kỷ này.

Nhưng đừng dừng ở đó. Catalog JS kia thực ra được đổ dữ liệu từ một JSON API ở phía nền, giống như đa số các trường hợp tương tự. Tôi trỏ cùng spider đó đến endpoint này và nhận về 8/8 sản phẩm chỉ trong 0.416s — không browser, không render, chỉ là gửi request đến đúng URL mà trang đã gọi sẵn và parse JSON trả về.

So sánh hai kết quả này là phiên bản thu nhỏ của triết lý “tái tạo request”. Trang đã render chỉ là lớp ngụy trang; dữ liệu thật ra nằm sau một API từ đầu đến cuối, và thiết kế của Scrapy hướng bạn đến việc đánh thẳng vào API thay vì phải trả chi phí cho headless browser chỉ để ngồi xem trang tự lắp ghép. Cách đó nhanh hơn, nhẹ hơn và ít hỏng vặt hơn — một giao thức API ổn định hơn hẳn việc phụ thuộc vào một đống DOM phía client. Điểm trừ là nó thủ công. Bạn phải mở network tab, tìm request, rồi tự mô phỏng headers và params của nó. Scrapy không tự đi săn API cho bạn; nó chỉ khiến việc gọi API trở nên cực kỳ dễ dàng một khi bạn đã tìm ra nó.

Hai giới hạn cần nói rõ. Khi thực sự không có request nền nào để tái tạo — tức dữ liệu được client-side rendering tạo ra hoàn toàn mà không có API phía sau — thì Scrapy cần một tích hợp headless browser do chính bạn gắn vào, và tôi không thử nhánh đó trong lần đánh giá này. Ngoài ra, mọi thứ ở trên đều được chạy trên các fixture nhỏ và trang demo công khai. Tôi không chạy một crawl từ 100 đến 1,000 trang, nên tôi không đưa ra bất kỳ khẳng định nào về bộ nhớ, throughput hay hành vi retry ở quy mô lớn — lõi bất đồng bộ và các cơ chế crawl là tín hiệu tích cực, nhưng tín hiệu không phải là số đo thực nghiệm.

Ưu và nhược điểm

Ưu điểm:

  • Thiết kế chỉ HTTP rất nhanh và nhẹ — thu hồi 12/12 dữ liệu tĩnh chỉ trong khoảng nửa giây, lấy 8/8 từ API JSON trong 0.416s, không tốn chi phí browser.
  • Cách “tái tạo request” thực sự hiệu quả: một trang JS trả về 0 node nhưng API nền lại cung cấp đủ 8 mục.
  • CSS và XPath selector dựa trên lxml giúp code trích xuất dễ đọc và chạy nhanh.
  • Feed export sang JSON/CSV/XML mà không cần viết thêm cơ chế xuất dữ liệu.
  • Xử lý lỗi rõ ràng — status 500 được bắt như một kết quả cần xử lý chứ không phải crash.
  • Kiểm soát crawl trưởng thành: concurrency, độ trễ, giới hạn độ sâu, AutoThrottle, robots.txt.
  • Giấy phép BSD-3-Clause thân thiện; cài đặt sạch trên máy hiện đại.

Nhược điểm:

  • Không render JavaScript theo thiết kế — trang do client render sẽ trả về 0 node cho đến khi bạn tự tìm API.
  • Việc tìm request nền là thủ công; Scrapy không tự chỉ ra endpoint cho bạn.
  • Stack phụ thuộc khá lớn (Twisted, lxml, cryptography, pyOpenSSL, parsel, tldextract) — ở đây cài êm, nhưng lâu nay vẫn là điểm hay vướng trên các nền tảng đặc biệt.
  • Cần nhiều code hơn so với các công cụ no-code hay auto-extraction; spider do bạn tự viết và bảo trì.
  • Tôi mới chỉ kiểm thử trên fixture nhỏ và site demo, chưa thử crawl quy mô lớn — độ tin cậy ở scale vẫn chưa được chứng minh trong lần này.

Phù hợp với ai, và ai nên đi qua

Scrapy manual API boundary

Scrapy dành cho các developer muốn kiểm soát ở cấp code và tư duy theo request chứ không theo trang. Nếu phản xạ đầu tiên của bạn khi gặp một site JavaScript chậm chạp là “ở đây chắc chắn có API nào đó”, thì công cụ này được sinh ra đúng để phục vụ kiểu suy nghĩ đó. Nó phù hợp với người thoải mái viết selector, đọc network tab và tự chịu trách nhiệm cho logic trích xuất từ đầu đến cuối. Với website tĩnh, catalog phân trang, hoặc bất kỳ thứ gì có endpoint JSON dễ tìm, Scrapy vừa nhanh vừa chính xác.

Bạn nên đi qua — hoặc ít nhất là ghép nó với công cụ khác — nếu việc viết và bảo trì spider code không phải là cách bạn muốn dành thời gian, hoặc nếu dữ liệu mục tiêu của bạn chỉ được render hoàn toàn ở client mà không có request tái tạo được và bạn không muốn tự gắn thêm headless browser. Và nếu ước mơ của bạn là trỏ một công cụ vào URL rồi lấy ngay output có cấu trúc sạch sẽ mà không cần tự viết quy tắc trích xuất, thì đó vốn chưa bao giờ là nhiệm vụ của Scrapy, và nó cũng chưa từng giả vờ như vậy.

Lựa chọn thay thế, và Thunderbit phù hợp ở đâu

Dùng thử Thunderbit để trích xuất dữ liệu web

Hãy bắt đầu từ điều bạn thực sự nhận được: một framework mã nguồn mở miễn phí mà bạn tự vận hành và tự bảo trì. Bạn sở hữu spider, stack phụ thuộc và cả công việc đi tìm request dữ liệu của từng site. Đổi lại, bạn không phải trả tiền trên mỗi request, giữ mọi thứ trong nội bộ và có quyền kiểm soát tuyệt đối. Với rất nhiều đội ngũ, đó là lựa chọn đúng đắn, và bài viết này không nhằm thuyết phục ai từ bỏ nó.

Điểm đánh đổi nằm ở bài toán render và thay đổi giao diện, và câu trả lời của Scrapy là: chính bạn phải tự giải quyết nó — bạn tìm API, bạn mô phỏng request, và với trường hợp không có API thì bạn tự gắn browser vào. Một AI scraping API được quản lý sẽ gỡ lớp đó khỏi vai bạn. Đó là vị trí mà Thunderbit đảm nhiệm trong bộ công cụ dành cho người dùng kỹ thuật — một AI scraping API cộng với MCP server và CLI, chứ không phải browser extension mà nhóm sales và ops thường dùng. POST /distill biến một trang thành Markdown sạch, sẵn sàng cho LLM; POST /extract trả về JSON có cấu trúc dựa trên schema bạn tự định nghĩa; và cả hai đều xử lý rendering JavaScript, anti-bot và nội dung động ở phía server — bao gồm cả trường hợp client-rendered mà Scrapy sẽ yêu cầu bạn dùng browser. Có MCP server dành cho AI agents và coding assistants (kèm thunderbit_suggest_fields miễn phí để xác định phạm vi trang trước khi bạn tốn gì cả), và có cả CLI qua npx @thunderbit/thunderbit-cli cho terminal, CI hoặc cron job.

Khác biệt không nằm ở chất lượng, mà ở quyền sở hữu. Scrapy là một framework kỹ thuật minh bạch: bạn tự duy trì spider, pipeline và chiến lược xử lý JavaScript, đổi lại bạn có toàn quyền kiểm soát mà không phải trả phí theo lần gọi. Bộ công cụ của Thunderbit thì đảm nhận phần render-and-extract như một dịch vụ quản lý sẵn, nên bạn khỏi phải lùng network tab và trả tiền theo số lần gọi. Quy mô nhỏ, ưu tiên code-first và thích tự nắm từng bước? Khả năng kiểm soát của Scrapy sẽ hợp hơn. Còn nếu bạn phải scale qua cả trăm website và không muốn tự mô phỏng request cho từng site, thì mô hình managed sẽ bỏ qua hẳn cả một nhóm công việc.

Với bức tranh rộng hơn, những bài benchmark này sẽ giúp bạn so sánh các lựa chọn lân cận: so sánh toàn diện các scraper mã nguồn mở, đánh giá Colly — crawler Go không cần browser, và đánh giá Scrapling với bộ chọn thích ứng.

Kết luận

Có nên dùng Scrapy không? Có — nếu bạn là developer muốn kiểm soát và đồng ý với triết lý của nó: đừng render trang, hãy tìm request phía sau nó. Trong quá trình thử nghiệm, triết lý đó phát huy đúng như lời hứa. Một catalog JavaScript cho HTTP fetcher 0 thẻ; API JSON đằng sau nó lại trả đủ 8 mục cho cùng một spider. Trích xuất tĩnh đạt 12/12, selector bài viết giữ sạch 3/3 đoạn nội dung khỏi boilerplate, đồ thị crawl tuân thủ giới hạn độ sâu trên 11 trang, và một trang trả về 500 cũng chỉ được xử lý như một status bình thường thay vì gây crash.

Tuy nhiên, cần nhìn nhận đúng quy mô của các kết luận này. Scrapy không render JavaScript, và nó sẽ không tự đi tìm API cho bạn — việc đó là phản xạ bạn phải tự xây. Stack phụ thuộc của nó đúng nghĩa là một framework đầy đủ và có thể gây vướng trên nền tảng lạ dù ở đây cài đặt rất sạch. Và tôi mới chỉ kiểm thử trên fixture và trang demo, chưa crawl hàng nghìn trang, nên hãy xem câu chuyện về scale là đầy hứa hẹn nhưng chưa được chứng minh trọn vẹn. Trong phạm vi đó, Scrapy là công cụ thể hiện rõ nhất một ý tưởng khá táo bạo nhưng âm thầm: cách nhanh nhất để đi qua một trang web thường không nằm ở việc đi qua chính trang web đó.

Dùng thử Thunderbit để trích xuất dữ liệu web Get Started Free

Câu hỏi thường gặp

Scrapy có scrape được các trang render bằng JavaScript không? Không với HTTP fetcher mặc định — nó trả về 0 node ở cả fixture JS lẫn trang Quotes JS công khai, vì nó chỉ tải HTML mà không chạy browser. Cách làm đúng là tìm request dữ liệu nền mà trang đang gọi rồi đánh trực tiếp vào đó; trong thử nghiệm của tôi, API JSON phía sau một catalog JS đã trả đủ 8 mục. Với những trang không có request tái tạo được, bạn phải tự tích hợp headless browser.

“Tái tạo request” thực sự nghĩa là gì? Phần lớn các trang động tải dữ liệu từ một API JSON ở nền rồi render ở phía client. Thay vì chạy browser để nhìn quá trình đó diễn ra, bạn mở network tab, tìm request API đó, rồi trỏ Scrapy trực tiếp vào nó. Cách này nhanh và ổn định hơn render — hợp đồng API ít thay đổi hơn DOM — nhưng đó là công việc thủ công, và Scrapy sẽ không tự tìm endpoint giúp bạn.

Cài Scrapy có khó không? Với tôi thì rất êm — pip install Scrapy==2.17.0 chạy xong không có lỗi biên dịch nào trong một venv mới trên macOS, dùng binary wheels. Nhưng nó kéo theo một stack khá lớn (Twisted, lxml, cryptography, pyOpenSSL, parsel, tldextract), và tài liệu chính thức vẫn cảnh báo về các xung đột phụ thuộc theo nền tảng trên một số hệ thống, nên nếu môi trường của bạn hơi đặc biệt thì hãy dành chỗ cho khâu này.

Scrapy hỗ trợ những định dạng đầu ra nào? Feed export hỗ trợ sẵn JSON, JSON Lines, CSV và XML — chỉ cần trỏ spider vào file là nó tự serialize item mà không cần code thêm. Trong lần chạy của tôi, một spider đã tạo ra cả JSON lẫn CSV chỉ trong một lượt. Lưu ý là nó xuất những field bạn chọn; nó không tự biến trang thành Markdown sạch.

Scrapy có miễn phí để dùng thương mại không? Có, vì nó dùng giấy phép BSD-3-Clause, vốn khá thoáng và thân thiện với thương mại. Như mọi khi, hãy kiểm tra lại giấy phép hiện tại trên repo trước khi xây dựng sản phẩm dựa trên nó, và hãy dùng user-agent, proxy cũng như rate limit một cách có trách nhiệm — có khả năng không đồng nghĩa với có quyền.

Ke
Ke
CTO tại Thunderbit | Chuyên gia Khoa học Dữ liệu cấp cao & ML Với gần một thập kỷ kinh nghiệm trong học máy và khoa học dữ liệu, Ke Shen là cựu sinh viên Đại học Columbia và từng là Chuyên gia Khoa học Dữ liệu cấp cao tại Walmart Labs. Sở hữu chuyên môn sâu về Python, R, Java và Thống kê, được đồng nghiệp công nhận, anh chia sẻ những góc nhìn thực chiến về cách đưa các thuật toán AI phức tạp từ lý thuyết vào kiến trúc sẵn sàng cho môi trường sản xuất.

Thử Thunderbit

Scrape lead và dữ liệu khác chỉ với 2 cú nhấp. Vận hành bằng AI.

Nhận Thunderbit Miễn phí
Trích xuất dữ liệu bằng AI
Dễ dàng chuyển dữ liệu sang Google Sheets, Airtable hoặc Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week