84 sao trên GitHub và con số này vẫn đang tiếp tục tăng. Yozh Crawler + Scraper là phần mềm miễn phí, mã nguồn mở và được phát triển công khai — hãy nhấn sao cho chúng tôi nếu công cụ này xứng đáng có một vị trí trong hệ thống công nghệ của bạn.
CyberYozh Data / Yozh Crawler
Phần mềm · Yozh Crawler

Chỉ cần nhập một URL nguồn, toàn bộ trang web sẽ được phát trực tuyến

Yozh Crawler thu thập dữ liệu trên một trang web bắt đầu từ một URL duy nhất và truyền trực tiếp mọi trang được phát hiện qua SSE. Công cụ này đảm nhận phần khó nhất của quá trình thu thập dữ liệu — mở rộng phạm vi, loại trừ trùng lặp, xác định phạm vi, tuân thủ quy tắc và thử lại — trong khi mỗi lần truy xuất trang đều được xử lý qua Yozh Scraper. Không có sự trùng lặp với Playwright, không phải là dịch vụ SaaS, chạy trên :8001.

$curl -N :8001/api/v1/crawl -d '{"seed_url":"https://site.com", "scope":{"mode":"same-domain","max_depth":2,"max_pages":500}}'

Thu thập dữ liệu

Yozh Crawler thu thập dữ liệu trên một trang web bắt đầu từ một URL hạt giống duy nhất và truyền trực tiếp mọi trang được phát hiện qua SSE. Nó đảm nhận toàn bộ quá trình khám phá — mở rộng phạm vi, loại trừ trùng lặp, xác định phạm vi, trích xuất liên kết, thử lại và tuân thủ các quy tắc lịch sự — trong khi việc truy xuất từng trang được ủy quyền cho Yozh Scraper qua HTTP. Chỉ có duy nhất một bộ công cụ Playwright cần vận hành, và mọi tính năng của trình trích xuất (proxy, chế độ ẩn danh, phiên làm việc, quy tắc trích xuất) cũng được áp dụng cho các trang web đã thu thập.

  • Điều kiện phạm visame-domain / subdomains / all / regex, với các mẫu bao gồm và loại trừ cùng các giới hạn max_depth / max_pages giới hạn cứng.
  • Loại bỏ trùng lặp dựa trên dấu vân tay — Các URL được chuẩn hóa rồi mã hóa băm (SHA1), do đó các truy vấn được sắp xếp lại và các biến thể có dấu gạch chéo ở cuối sẽ được gộp lại thành một lượt truy cập.
  • Cơ chế luân phiên theo từng miền — một máy chủ chậm hoặc có dung lượng lớn sẽ không thể làm cạn kiệt nguồn công nhân của các máy chủ khác.
  • Bộ giới hạn tốc độ thích ứng — một thùng token toàn cục cho từng miền (có độ dao động) được chia sẻ giữa các tác vụ; một 429 giảm một nửa RPS trong khoảng thời gian làm mát.
  • Tình trạng phiên làm việc — Hệ thống chấm điểm theo phong cách Crawlee: 401/403/429 khi phiên làm việc kết thúc, các lỗi sẽ làm tăng điểm số của phiên, còn thành công sẽ làm giảm điểm số; luân chuyển phiên khi điểm số ≥ 3 hoặc sau 50 lần sử dụng.
  • Phát trực tuyến SSE — mỗi tác vụ đều phát ra stats, page, page_error, và các sự kiện done / cancelled . Hãy xử lý các kết quả ngay khi chúng xuất hiện.
URL gốchttp://localhost:8001
Tài liệu OpenAPIhttp://localhost:8001/docs
Điểm cuối MCPhttp://localhost:8001/mcp
Dịch vụ hỗ trợ. Trình thu thập dữ liệu ủy quyền mọi tác vụ lấy dữ liệu cho Yozh Scraper, vì vậy hãy khởi động cả hai cùng lúc — trình trích xuất trên :8000 và trình thu thập dữ liệu trên :8001.

Bắt đầu nhanh

Trình thu thập dữ liệu được nối dây vào gốc docker-compose.yml và chạy song song với trình trích xuất:

bash
docker compose up --build
# scraper  → http://localhost:8000
# crawler  → http://localhost:8001

Hoặc chạy nó trên máy cục bộ mà không cần Docker — chỉ SCRAPER_URL vào một trình thu thập dữ liệu đang chạy:

bash
cd yozh-crawler
pip install -r requirements.txt
cp .env.example .env          # edit SCRAPER_URL if needed
python -m uvicorn src.main:app --reload --port 8001

Cách sử dụng cơ bản

Gửi yêu cầu thu thập dữ liệu kèm theo seed_url và một scope. Lời gọi này sẽ trả về một job_id ngay lập tức; sau đó, quá trình thu thập dữ liệu sẽ chạy ở chế độ nền trên các tác vụ công việc.

cURL
curl -X POST http://localhost:8001/api/v1/crawl 
  -H "Content-Type: application/json" 
  -d '{
    "seed_url": "https://example.com",
    "scope": {"mode": "same-domain", "max_depth": 2, "max_pages": 50,
              "per_domain_rps": 1.0, "per_domain_concurrency": 1},
    "scrape_options": {"proxy_type": "none"},
    "enable_scraping": false
  }'

Kết quả trả về chỉ là mã công việc:

JSON
{ "job_id": "crawl_abc123" }

Từ đây, bạn có thể phát trực tiếp các sự kiện hoặc truy vấn công việc để lấy bản ghi đầy đủ.

Khám phá so với khai thác — nút enable_scraping chuyển đổi

Cùng một công cụ thu thập dữ liệu hoạt động theo cả hai hướng. Một biến boolean dùng để lựa chọn giữa chế độ khám phá tiết kiệm tài nguyên và chế độ thu thập dữ liệu toàn diện — và mỗi chế độ sử dụng cấu hình proxy riêng, do đó không xảy ra hiện tượng ảnh hưởng lẫn nhau.

enable_scraping: false

Bản đồ khám phá

Một lần quét nhẹ. Công cụ thu thập dữ liệu vẫn hiển thị từng trang (để phát hiện các liên kết được tạo bằng JavaScript), nhưng trình thu thập dữ liệu chỉ giữ lại phần khung cơ bản — rất lý tưởng cho sơ đồ trang web, kiểm tra liên kết và phát hiện sự thay đổi.

  • Giữ url · parent_url · depth · status · took_ms
  • Chèn mã HTML thô, ảnh chụp màn hình và dữ liệu đã trích xuất
  • Sử dụng loại rẻ hơn crawl_proxy
  • Tải trọng nhỏ nhất, tốc độ di chuyển chậm nhất
enable_scraping: true

Thu thập toàn bộ

Mỗi trang đã truy cập đều được lưu lại kèm theo ScrapeResponse — mã HTML thô, ảnh chụp màn hình (tùy chọn) và bất kỳ trường dữ liệu nào từ quy tắc trích xuất của bạn. Thu thập và cấu trúc dữ liệu chỉ trong một lần xử lý.

  • Giữ nguyên toàn bộ ScrapeResponse trên mỗi trang
  • raw_html · screenshot · đã trích xuất data
  • Công dụng scrape_options.proxy_*
  • Chuyển extract các quy tắc để thu được JSON sạch
Lựa chọn proxy. crawl_proxy chỉ được sử dụng khi enable_scraping=false; scrape_options.proxy_* được sử dụng khi true. Nếu crawl_proxynull, thì scrape_options proxy sẽ được sử dụng bất kể chế độ nào.

Phạm vi thu thập dữ liệu

Phạm vi xác định giới hạn của quá trình thu thập dữ liệu: nơi mà quá trình này được phép truy cập, và mức độ tác động tối đa được phép đối với từng máy chủ. Đây là scope đối tượng trong yêu cầu.

TrườngKiểuMặc địnhMô tả
modesame-domain · subdomains · all · regexsame-domainNhững liên kết nào nằm trong phạm vi. regex phù hợp với include_patterns.
include_patternsstring[][]Các mẫu biểu thức chính quy (Regex) mà một URL phải phù hợp để được đưa vào hàng đợi (được sử dụng bởi regex chế độ / như một danh sách cho phép).
exclude_patternsstring[][]Các mẫu biểu thức chính quy (Regex) loại bỏ một URL ngay cả khi URL đó nằm trong phạm vi áp dụng.
max_depthint3Độ sâu liên kết tối đa tính từ nút gốc (nút gốc có độ sâu là 0).
max_pagesint500Giới hạn tối đa về số trang được truy cập trước khi quá trình thu thập dữ liệu kết thúc.
per_domain_rpsfloat1.0Tốc độ nạp lại “thùng token” cho mỗi miền (yêu cầu/giây).
per_domain_concurrencyint1Số lượng yêu cầu tối đa trong một lần truy cập đối với một tên miền duy nhất.
Phạm vi “subdomains” đơn giản. Phương pháp này sử dụng hai nhãn cuối cùng làm miền có thể đăng ký, do đó nó sẽ khớp quá mức với các máy chủ trong Danh sách hậu tố công khai (Public Suffix List) như github.io hoặc co.uk. Nên ưu tiên same-domain hoặc regex cho những trường hợp đó.

Kết quả phát trực tuyến (SSE)

Mỗi tác vụ đều cung cấp một luồng sự kiện do máy chủ gửi (Server-Sent Events). Hãy đọc luồng này để thực hiện các thao tác trên các trang ngay khi chúng được phát hiện, thay vì phải chờ quá trình thu thập dữ liệu hoàn tất.

cURL
curl -N http://localhost:8001/api/v1/crawl/crawl_abc123/events

Dòng dữ liệu phát ra năm loại sự kiện:

Sự kiệnKhi nào
statsBản tóm tắt tiến độ định kỳ (đã truy cập / đang chờ xử lý / thất bại / bỏ qua do trùng lặp / nằm ngoài phạm vi / thử lại).
pageMỗi URL đã truy cập có một mục. Chứa đầy đủ ScrapeResponse trong chế độ thu thập, chỉ lưu trữ siêu dữ liệu tối thiểu trong chế độ khám phá.
page_errorMột URL đã thất bại sau khi đã thử lại tất cả các lần.
doneTerminal — quá trình quét đã hoàn tất bình thường.
cancelledTerminal — quá trình thu thập dữ liệu đã bị hủy.

Một page sự kiện trong chế độ khám phá trông như sau:

JSON
{
  "event": "page",
  "url": "https://example.com/docs/intro",
  "parent_url": "https://example.com/docs",
  "depth": 2,
  "status_code": 200,
  "took_ms": 812,
  "scrape_response": null
}

Tình trạng và kết quả

Bạn thích phương thức thăm dò hơn? Bản ghi công việc có thể được truy vấn bất cứ lúc nào — kể cả trong quá trình thu thập dữ liệu, với các trang đã được phát hiện cho đến thời điểm đó. /results là một tên gọi khác của điểm cuối công việc, được giữ lại để đảm bảo tính đối xứng với trình thu thập dữ liệu.

cURL
curl http://localhost:8001/api/v1/crawl/crawl_abc123
curl http://localhost:8001/api/v1/crawl/crawl_abc123/results
JSON
{
  "job_id": "crawl_abc123",
  "status": "running",
  "stats": {
    "visited": 47, "queued": 12, "failed": 0,
    "dedup_skipped": 9, "out_of_scope": 31, "retries_total": 2
  },
  "pages": [
    { "url": "https://example.com/", "parent_url": null,
      "depth": 0, "status_code": 200, "took_ms": 640 }
  ]
}
status di chuyển qua queuedrunningdone (hoặc failed / cancelled).

Hủy quá trình thu thập dữ liệu

Dừng một tác vụ đang chạy bằng lệnh DELETE. Hủy nhẹ là tùy chọn mặc định và là lựa chọn an toàn.

cURL
# soft — stop scheduling, let in-flight requests drain
curl -X DELETE "http://localhost:8001/api/v1/crawl/crawl_abc123?hard=false"

# hard — abort in-flight asyncio tasks immediately
curl -X DELETE "http://localhost:8001/api/v1/crawl/crawl_abc123?hard=true"
Việc hủy cứng sẽ khiến trình thu thập dữ liệu bị bỏ lại một mình. A ?hard=true sẽ hủy yêu cầu đang được xử lý của trình thu thập dữ liệu, nhưng trình thu thập dữ liệu không có cách nào biết được điều đó — quá trình hiển thị trang của nó vẫn hoàn tất bình thường. Nên ưu tiên hủy mềm trừ khi bạn bắt buộc phải dừng ngay lập tức.

MCP

fastapi-mcp được triển khai tại /mcp dưới dạng một điểm cuối HTTP có thể phát trực tuyến. Chỉ cần di chuột hoặc đặt con trỏ vào đó, các công cụ sẽ tự động xuất hiện:

  • health
  • create_crawl
  • get_crawl
  • get_crawl_results
  • cancel_crawl
~/.claude/settings.json
"open-crawler": {
  "type": "http",
  "url": "http://localhost:8001/mcp"
}
Điểm cuối SSE stream_crawl_events được loại trừ một cách có chủ đích khỏi MCP — các phản hồi truyền phát không phù hợp với công cụ yêu cầu/phản hồi.

Tài liệu tham khảo về cấu hình

Yêu cầu — CrawlRequest

TrườngKiểuMặc địnhMô tả
seed_urlchuỗi (URL)bắt buộcĐịa chỉ URL duy nhất mà quá trình thu thập dữ liệu bắt đầu từ đó.
scopeCrawlScopedefaultsPhạm vi và tính lịch sự — xem Phạm vi Crawl.
scrape_optionsScrapeOptionsdefaultsĐược chuyển tiếp nguyên văn đến công cụ thu thập dữ liệu theo từng trang (url được chèn vào).
crawl_proxyScrapeOptions · nullnullProxy giá rẻ được sử dụng ở chế độ khám phá. Chỉ proxy_type / proxy_pool_id / proxy_geo được đọc.
enable_scrapingboolfalseHãy giữ nguyên ScrapeResponse trên mỗi trang (true) hoặc chỉ siêu dữ liệu khám phá (false).

Mỗi trang — ScrapeOptions (đã chọn)

TrườngKiểuMặc địnhMô tả
proxy_typenone · mobile · res_static · res_rotating · dc_static · …noneNhóm máy chủ proxy mà các yêu cầu truy xuất trang đi qua.
devicedesktop · mobiledesktopKhung xem / Hồ sơ trình duyệt.
renderbooltrueHiển thị bằng trình duyệt (cần thiết cho các liên kết được tạo bằng JavaScript).
stealthbooltrueÁp dụng các biện pháp tăng cường bảo mật chống phát hiện.
wait_untildomcontentloaded · networkidledomcontentloadedKhi trang được coi là đã sẵn sàng.
screenshotboolfalseChụp ảnh màn hình (chế độ thu thập).
extractExtractRule · nullnullQuy tắc trường CSS/XPath → có cấu trúc data theo từng trang.
session_idchuỗi · nullnullTái sử dụng phiên thu thập dữ liệu đã được xác thực — xem phần “Thu thập dữ liệu đã được xác thực”.

Biến môi trường

BiếnMặc địnhGhi chú
SCRAPER_URLhttp://web-scraper:8000Trình thu thập dữ liệu đầu vào (sử dụng tên dịch vụ Docker trong mạng Compose).
WORKERS2Số lượng tác vụ thu thập dữ liệu song song.
QUEUE_MAXSIZE200Độ sâu hàng đợi các công việc đang chờ xử lý.
JOB_TIMEOUT_MS3_600_000Giới hạn thời gian thực cho một tác vụ thu thập dữ liệu.
SCRAPER_JOB_TIMEOUT_MS120_000Thời gian chờ tối đa cho mỗi yêu cầu của trình thu thập dữ liệu theo trang.
MAX_RETRIES3Số lần thử lại cho mỗi yêu cầu khi xảy ra lỗi tạm thời.
RETRY_HTTP_CODES[408,429,500,502,503,504]Các mã trạng thái kích hoạt việc thử lại.
RETRY_BACKOFF_MAX30.0Giới hạn trên của thời gian lùi theo hàm mũ (giây).
SESSION_MAX_ERROR_SCORE3.0Ngưỡng kết thúc phiên.
SESSION_MAX_USAGE50Xoay vòng phiên làm việc sau N lần sử dụng.
SESSION_BLOCKED_CODES[401,403,429]Các đoạn mã giúp kết thúc phiên làm việc ngay lập tức.

Tham khảo API

Phương thứcĐường dẫnMục đích
POST/api/v1/crawlTạo một công việc. Trả về {"job_id":"…"}.
GET/api/v1/crawl/{id}Bản ghi công việc — trạng thái, số liệu thống kê, số trang đã hoàn thành.
GET/api/v1/crawl/{id}/resultsTên gọi khác của bản ghi công việc.
GET/api/v1/crawl/{id}/eventsChuyên ngành SSE (stats/page/page_error/done/cancelled).
DELETE/api/v1/crawl/{id}?hard=boolHủy công việc (hủy tạm thời hoặc hủy vĩnh viễn).
GET/api/v1/healthSức khỏe + khả năng tiếp cận của trình trích xuất.

Các chi tiết quan trọng

Không có xác thực (phiên bản 1). Không có điểm cuối nào được xác thực — dịch vụ này được thiết kế dành cho các mạng nội bộ hoặc mạng đáng tin cậy. Bất kỳ ai có thể truy cập vào dịch vụ này đều có thể gửi yêu cầu POST để khởi chạy quá trình thu thập dữ liệu với một giá trị khởi đầu tùy ý và biến nó thành một proxy SSRF. Hãy đảm bảo dịch vụ này nằm trong VPC của bạn hoặc phía sau cổng xác thực riêng của bạn.
robots.txt không được tham khảo. Trình thu thập dữ liệu sẽ truy cập mọi URL nằm trong phạm vi, bất kể /robots.txt. Bạn có trách nhiệm tuân thủ các quy tắc robots và điều khoản của trang web đối với các mục tiêu mà bạn không sở hữu — hãy sử dụng exclude_patterns và giới hạn tốc độ để duy trì sự lịch sự.
Không có tính bền vững. Các tác vụ tồn tại trong bộ nhớ và sẽ được đặt lại khi khởi động lại container (tương tự như scraper). Để đảm bảo tính bền vững, hãy truyền luồng dữ liệu SSE vào kho lưu trữ của riêng bạn (tệp, Postgres, Kafka) ngay khi các trang dữ liệu đến. Hãy khởi động lại các tiến trình chạy lâu dài theo định kỳ — các tác vụ đã hoàn thành sẽ tích lũy trong kho lưu trữ.
Quá trình thu thập dữ liệu đã được xác thực. Tạo một phiên làm việc trên công cụ thu thập dữ liệu (POST /sessions + POST /sessions/{id}/login), sau đó truyền scrape_options.session_id. Trình thu thập dữ liệu truyền đi và nhận lại cookie cùng trạng thái lưu trữ cho mỗi yêu cầu, do đó mọi trang được thu thập đều nhận được trạng thái đã xác thực.
Ví dụ trực tiếp

Cùng miền — lựa chọn mặc định an toàn

Chỉ ở đúng host hạt giống, giới hạn độ sâu và số trang, giữ lịch sự. Chế độ khám phá (enable_scraping: false) chỉ giữ lại bộ khung của mỗi trang.


            

Được các đội ngũ phân tích dữ liệu và các nhà phát triển AI yêu thích

Những người đang phát triển ứng dụng với Yozh nói gì

5,0 / 5 · Đánh giá 5
GitHub
Chỉ trong một buổi chiều, chúng tôi đã thay thế cụm Playwright nội bộ bằng Yozh. Điểm cuối MCP được tích hợp trực tiếp vào tác nhân Claude của chúng tôi — không cần viết mã kết nối, trình thu thập dữ liệu và trình trích xuất dữ liệu đều hoạt động ngay lập tức.
Marcus Reinhardt Kỹ sư Dữ liệu Trưởng Northwind Analytics
X
Hệ thống cài đặt sẵn chính là tính năng nổi bật nhất. Chúng tôi chỉ cần truyền vào tên nguồn là sẽ nhận lại được dữ liệu JSON đã được làm sạch; tính năng tự khắc phục lỗi thậm chí còn phát hiện ra hai thay đổi về bố cục của Amazon trước khi chúng tôi kịp nhận ra.
Priya Nair Người sáng lập ScrapeStack
Reddit
Cuối cùng thì cũng có một công cụ thu thập dữ liệu mã nguồn mở coi các máy chủ proxy và phiên làm việc là yếu tố then chốt. Chúng tôi triển khai công cụ này để truy cập các cổng thông tin đối tác có yêu cầu đăng nhập — các phiên làm việc được duy trì và kết quả luôn nhất quán trên các khu vực.
Daniel Osei Kỹ sư hệ thống phía máy chủ Loopfeed
X
Sau khi kết nối với Cursor qua MCP, hiện tại agent của tôi có thể lấy dữ liệu web thời gian thực ngay trong quá trình thực hiện tác vụ. Tính năng thu thập dữ liệu theo thời gian thực qua SSE chính là điều mà các quy trình làm việc của agent còn thiếu.
Elena Kovac Kỹ sư Trí tuệ nhân tạo Vektor Labs
GitHub
Chúng tôi đã ngừng sử dụng một API trích xuất dữ liệu trả phí để cắt giảm chi phí và chuẩn bị tinh thần cho việc chất lượng dịch vụ sẽ giảm sút — nhưng kết quả lại hoàn toàn ngược lại. Hệ thống tự vận hành, không tính phí theo từng yêu cầu, và cấu trúc dữ liệu đầu ra còn gọn gàng hơn so với dịch vụ mà trước đây chúng tôi phải trả tiền để sử dụng.
Sofia Almeida Trưởng phòng Kỹ thuật Tabbly
Nguồn mở · Giấy phép MIT · 84 ★

Hãy nhập một URL vào. Xem trang web được tải về ngay lập tức

Yozh Crawler được phân phối trong cùng một kho lưu trữ với công cụ trích xuất dữ liệu — chỉ một docker compose up và bạn đã có cả tính năng khám phá + trích xuất, sẵn sàng cho MCP, trên hạ tầng của riêng bạn. Miễn phí. Mãi mãi. Hãy đánh dấu sao cho chúng tôi nếu công cụ này xứng đáng có mặt trong hệ thống của bạn.

Yozh Crawler + Scraper được phát hành theo giấy phép MIT. Hãy sử dụng nó. Hãy tạo nhánh từ nó. Hãy phát triển dựa trên nó.