งานตามกำหนดเวลา
ระบบอัตโนมัติสำหรับการดึงข้อมูล การครอล และการค้นหาแบบเกิดซ้ำด้วยตาราง cron
บทนำ
งานตามกำหนดเวลา (Scheduled Tasks) ช่วยให้คุณระบบอัตโนมัติการดึงข้อมูลเว็บ การครอล และการรวบรวมข้อมูลแบบเกิดซ้ำด้วยนิพจน์ cron มาตรฐาน เหมาะสำหรับมอนิเตอร์เว็บ ติดตามราคา เก็บถาวรเนื้อหา รวมผลค้นหา หรือการรวบรวมข้อมูลเป็นระยะ
คุณสมบัติหลัก: ตารางด้วย cron พร้อมเขตเวลา โหมด concurrency หลายแบบ การหยุดอัตโนมัติเมื่อล้มเหลวต่อเนื่อง การจัดการเครดิต และการเชื่อม webhook เพื่อแจ้งเหตุการณ์
คุณสมบัติหลัก
- ตารางด้วย Cron: ใช้ไวยากรณ์ cron มาตรฐานกำหนดเวลารัน
- รองรับเขตเวลา: รันงานในเขตเวลาใดก็ได้ (เช่น Asia/Shanghai, America/New_York)
- ควบคุม concurrency: สองโหมด — ข้ามหรือเข้าคิวเมื่อรันซ้อน
- หยุดอัตโนมัติ: หยุดชั่วคราวหลังล้มเหลวต่อเนื่องเพื่อปกป้องทรัพยากร
- จัดการเครดิต: จำกัดการรันต่อวันและประมาณการเครดิต
- ประวัติการรัน: ติดตามทุกครั้งพร้อมสถานะและตัวชี้วัด
- เชื่อม Webhook: รับการแจ้งเตือนแบบเรียลไทม์สำหรับเหตุการณ์ของงาน
เอนด์พอยต์ API
POST /v1/scheduled-tasks # สร้างงานตามกำหนดเวลา
GET /v1/scheduled-tasks # รายการงานทั้งหมด
GET /v1/scheduled-tasks/:taskId # รายละเอียดงาน
PUT /v1/scheduled-tasks/:taskId # อัปเดตงาน
PATCH /v1/scheduled-tasks/:taskId/pause # หยุดงานชั่วคราว
PATCH /v1/scheduled-tasks/:taskId/resume # ดำเนินงานต่อ
DELETE /v1/scheduled-tasks/:taskId # ลบงาน
GET /v1/scheduled-tasks/:taskId/executions # ประวัติการรัน
DELETE /v1/scheduled-tasks/:taskId/executions/:executionId # ยกเลิกการรันครั้งหนึ่งเริ่มต้นอย่างรวดเร็ว
สร้างงานดึงข้อมูลรายวัน
curl -X POST "https://api.anycrawl.dev/v1/scheduled-tasks" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily Tech News",
"description": "Scrape Hacker News daily at 9 AM",
"cron_expression": "0 9 * * *",
"timezone": "Asia/Shanghai",
"task_type": "scrape",
"task_payload": {
"url": "https://news.ycombinator.com",
"engine": "cheerio",
"formats": ["markdown"]
},
"concurrency_mode": "skip",
"max_executions_per_day": 1
}'การตอบกลับ
{
"success": true,
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"next_execution_at": "2026-01-28T01:00:00.000Z"
}
}คู่มือนิพจน์ Cron
นิพจน์ cron ใช้ 5 ฟิลด์กำหนดตาราง:
* * * * *
│ │ │ │ │
│ │ │ │ └─ Day of week (0-7, 0 and 7 = Sunday)
│ │ │ └─── Month (1-12)
│ │ └───── Day of month (1-31)
│ └─────── Hour (0-23)
└───────── Minute (0-59)ตัวอย่างทั่วไป
| Expression | คำอธิบาย | เวลารัน |
|---|---|---|
0 9 * * * | ทุกวัน 09:00 | 09:00:00 ทุกวัน |
*/15 * * * * | ทุก 15 นาที | :00, :15, :30, :45 |
0 */6 * * * | ทุก 6 ชั่วโมง | 00:00, 06:00, 12:00, 18:00 |
0 9 * * 1 | ทุกวันจันทร์ 09:00 | จันทร์ 09:00:00 |
0 0 1 * * | วันแรกของเดือน | วันที่ 1 เวลา 00:00:00 |
30 2 * * 0 | ทุกวันอาทิตย์ 02:30 | อาทิตย์ 02:30:00 |
ใช้ crontab.guru เพื่อตรวจสอบและทำความเข้าใจนิพจน์ cron
พารามิเตอร์คำขอ
การตั้งค่างาน
| พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|---|
name | string | ใช่ | - | ชื่องาน (1–255 ตัวอักษร) |
description | string | ไม่ | - | คำอธิบายงาน |
cron_expression | string | ใช่ | - | นิพจน์ cron มาตรฐาน (5 ฟิลด์) |
timezone | string | ไม่ | "UTC" | เขตเวลาการรัน (เช่น "Asia/Shanghai") |
task_type | string | ใช่ | - | ชนิดงาน: "scrape", "crawl", "search", หรือ "template" |
task_payload | object | ใช่ | - | การตั้งค่างาน (ดูด้านล่าง) |
ควบคุม concurrency
| พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|---|
concurrency_mode | string | ไม่ | "skip" | โหมด: "skip" หรือ "queue" |
max_executions_per_day | number | ไม่ | - | จำกัดการรันต่อวัน |
เมตadata การรัน (อ่านอย่างเดียว)
ฟิลด์เหล่านี้คืนในการตอบกลับงานและไม่รับใน body ของ create/update:
min_credits_required: เครดิตขั้นต่ำโดยประมาณต่อการรันหนึ่งครั้ง (คำนวณโดยเซิร์ฟเวอร์)consecutive_failures: จำนวนครั้งล้มเหลวต่อเนื่องสำหรับการหยุดอัตโนมัติ
เชื่อม Webhook
| พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|---|
webhook_ids | string[] | ไม่ | - | อาร์เรย์ UUID การสมัคร webhook ที่จะทริกเกอร์ |
webhook_url | string | ไม่ | - | URL webhook โดยตรง (สร้างการสมัครแบบโดยนัย) |
ใช้ webhook_ids อ้างการสมัครที่มีอยู่ หรือให้ webhook_url เพื่อสร้างการสมัครแบบโดยนัยสำหรับงานนี้
เมตadata
| พารามิเตอร์ | ชนิด | จำเป็น | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|---|
tags | string[] | ไม่ | - | แท็กจัดกลุ่ม |
metadata | object | ไม่ | - | เมตadata กำหนดเอง |
เพย์โหลดงาน
งาน Scrape
{
"url": "https://example.com/page",
"engine": "cheerio",
"formats": ["markdown"],
"timeout": 60000,
"wait_for": 2000,
"include_tags": ["article", "main"],
"exclude_tags": ["nav", "footer"]
}งาน Crawl
{
"url": "https://example.com",
"engine": "playwright",
"options": {
"max_depth": 3,
"limit": 50,
"strategy": "same-domain",
"exclude_paths": ["/admin/*", "/api/*"],
"scrape_options": {
"formats": ["markdown"]
}
}
}งาน Search
{
"query": "artificial intelligence news",
"engine": "google",
"limit": 20,
"country": "US",
"lang": "en",
"timeRange": "day"
}งาน Template
{
"template_id": "my-search-template",
"query": "machine learning tutorials",
"variables": {
"lang": "en"
}
}สำหรับ task_type: "template" task_payload ต้องมี:
template_id(จำเป็น): เทมเพลตที่จะรัน- ฟิลด์อินพุตตามเอนด์พอยต์ที่เทมเพลตนั้นต้องการ (เช่น
urlสำหรับเทมเพลต scrape/crawl,queryสำหรับ search) variables(ไม่บังคับ) สำหรับอินพุตไดนามิกของเทมเพลต
โหมด concurrency
skip (แนะนำ)
หากการรันครั้งก่อนยังไม่จบ ให้ข้ามการรันปัจจุบัน
เหมาะกับ: งานที่อาจใช้เวลานานกว่าช่วงระหว่างการรัน
ตัวอย่าง: งานครอลทุกชั่วโมงแต่บางครั้งใช้ 90 นาที
queue
เข้าคิวการรันใหม่และรอให้ครั้งก่อนจบ
เหมาะกับ: งานที่ทุกครั้งต้องรันไม่ข้าม
ตัวอย่าง: การรวบรวมข้อมูลสำคัญที่ห้ามพลาดรอบ
การจัดการงาน
รายการงานทั้งหมด
curl -X GET "https://api.anycrawl.dev/v1/scheduled-tasks" \
-H "Authorization: Bearer <your-api-key>"การตอบกลับ
{
"success": true,
"data": [
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "Daily Tech News",
"task_type": "scrape",
"cron_expression": "0 9 * * *",
"timezone": "Asia/Shanghai",
"is_active": true,
"is_paused": false,
"next_execution_at": "2026-01-28T01:00:00.000Z",
"total_executions": 45,
"successful_executions": 43,
"failed_executions": 2,
"consecutive_failures": 0,
"last_execution_at": "2026-01-27T01:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z"
}
]
}หยุดงานชั่วคราว
หยุดงานเพื่อหยุดการรันชั่วคราว พารามิเตอร์ reason จะถูกเก็บเป็น pause_reason ในระเบียนงาน
curl -X PATCH "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId/pause" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"reason": "Maintenance period"
}'การตอบกลับ
{
"success": true,
"message": "Task paused successfully",
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"is_paused": true,
"pause_reason": "Maintenance period"
}
}ดำเนินงานต่อ
curl -X PATCH "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId/resume" \
-H "Authorization: Bearer <your-api-key>"อัปเดตงาน
curl -X PUT "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"cron_expression": "0 10 * * *",
"description": "Updated description"
}'การตอบกลับ
{
"success": true,
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "Daily Tech News",
"description": "Updated description",
"task_type": "scrape",
"cron_expression": "0 10 * * *",
"timezone": "Asia/Shanghai",
"task_payload": {
"url": "https://news.ycombinator.com",
"engine": "cheerio",
"formats": ["markdown"]
},
"concurrency_mode": "skip",
"is_active": true,
"is_paused": false,
"next_execution_at": "2026-01-28T02:00:00.000Z",
"total_executions": 45,
"successful_executions": 43,
"failed_executions": 2,
"consecutive_failures": 0,
"last_execution_at": "2026-01-27T01:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-27T12:00:00.000Z",
"icon": "FileText"
}
}ใส่เฉพาะฟิลด์ที่ต้องการอัปเดต ฟิลด์อื่นคงเดิม
ลบงาน
curl -X DELETE "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId" \
-H "Authorization: Bearer <your-api-key>"การลบงานจะลบประวัติการรันทั้งหมดด้วย
ประวัติการรัน
ดึงรายการการรัน
curl -X GET "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId/executions?limit=20" \
-H "Authorization: Bearer <your-api-key>"การตอบกลับ
{
"success": true,
"data": [
{
"uuid": "exec-uuid-1",
"scheduled_task_uuid": "task-uuid",
"execution_number": 45,
"status": "completed",
"started_at": "2026-01-27T01:00:00.000Z",
"completed_at": "2026-01-27T01:02:15.000Z",
"duration_ms": 135000,
"job_uuid": "job-uuid-1",
"triggered_by": "scheduler",
"scheduled_for": "2026-01-27T01:00:00.000Z",
"error_message": null,
"credits_used": 5,
"items_processed": 1,
"items_succeeded": 1,
"items_failed": 0,
"job_status": "completed",
"job_success": true,
"icon": "CircleCheck"
}
]
}หมายเหตุ: ฟิลด์ credits_used, items_processed, items_succeeded, items_failed, job_status, และ job_success ดึงจากระเบียนงานที่เกี่ยวข้องผ่าน JOIN duration_ms คำนวณจาก started_at และ completed_at
ยกเลิกการรันครั้งหนึ่ง
ยกเลิกการรันที่กำลัง pending หรือ running มีประโยชน์เมื่อต้องหยุดเฉพาะครั้งโดยไม่หยุดทั้งงาน
curl -X DELETE "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId/executions/:executionId" \
-H "Authorization: Bearer <your-api-key>"การตอบกลับ
{
"success": true,
"message": "Execution cancelled successfully"
}ยกเลิกได้เฉพาะการรันที่สถานะ pending หรือ running การรันที่เสร็จแล้ว ล้มเหลว หรือยกเลิกแล้วจะคืนข้อผิดพลาด
การจัดการเมื่อล้มเหลวอัตโนมัติ
หยุดอัตโนมัติเมื่อล้มเหลวต่อเนื่อง
งานจะถูกหยุดอัตโนมัติหลังล้มเหลวต่อเนื่อง 5 ครั้ง เพื่อป้องกันการสิ้นเปลืองทรัพยากรและการเรียก API เกิน
ดำเนินต่อ: กดดำเนินงานต่อด้วยมือหลังแก้สาเหตุ
curl -X PATCH "https://api.anycrawl.dev/v1/scheduled-tasks/:taskId/resume" \
-H "Authorization: Bearer <your-api-key>"ติดตามความล้มเหลว
ติดตามด้วยฟิลด์ consecutive_failures ในสถานะงาน:
{
"consecutive_failures": 3,
"failed_executions": 5,
"successful_executions": 40
}ติดตามฟิลด์ consecutive_failures ค่าสูงบ่งชี้ปัญหาซ้ำที่ต้องแก้
เชื่อมกับ Webhooks
สมัครรับเหตุการณ์งานด้วย webhook:
curl -X POST "https://api.anycrawl.dev/v1/webhooks" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Task Notifications",
"webhook_url": "https://your-domain.com/webhook",
"event_types": ["task.executed", "task.failed", "task.paused"],
"scope": "all"
}'ดูรายละเอียดใน Webhooks
กรณีใช้งานทั่วไป
มอนิเตอร์ราคา
ตรวจราคาสินค้าทุกชั่วโมง:
{
"name": "Hourly Price Tracker",
"cron_expression": "0 * * * *",
"task_type": "scrape",
"task_payload": {
"url": "https://shop.example.com/product/12345",
"engine": "cheerio",
"formats": ["markdown"]
},
"concurrency_mode": "skip"
}สำรองเอกสารรายสัปดาห์
ครอลและเก็บถาวรเอกสารทุกสัปดาห์:
{
"name": "Weekly Docs Backup",
"cron_expression": "0 3 * * 0",
"timezone": "UTC",
"task_type": "crawl",
"task_payload": {
"url": "https://docs.example.com",
"engine": "playwright",
"options": {
"max_depth": 10,
"limit": 500
}
},
"max_executions_per_day": 1
}รวมข่าวรายวัน
ดึงข้อมูลจากหลายแหล่งข่าวทุกวัน:
{
"name": "Morning News Digest",
"cron_expression": "0 6 * * *",
"timezone": "America/New_York",
"task_type": "scrape",
"task_payload": {
"url": "https://news.example.com",
"engine": "cheerio",
"formats": ["markdown"]
},
"max_executions_per_day": 1
}ข่าวกรองคู่แข่ง
ติดตามการกล่าวถึงคู่แข่งและแนวโน้มอุตสาหกรรมทุกชั่วโมง:
{
"name": "Competitor Monitoring",
"cron_expression": "0 * * * *",
"task_type": "search",
"task_payload": {
"query": "YourCompany OR CompetitorA OR CompetitorB",
"engine": "google",
"limit": 50,
"timeRange": "day"
},
"concurrency_mode": "skip"
}แนวทางปฏิบัติที่ดี
1. เลือกช่วง Cron ให้เหมาะสม
- หลีกเลี่ยงตารางถี่เกินไป (< 1 นาที) เพื่อลดปัญหา rate limit
- พิจารณาความถี่อัปเดตของเว็บเมื่อตั้งช่วง
- ใช้เขตเวลาสำหรับเวลาตามสถานที่
2. ตั้งโหมด concurrency ให้ถูก
- ใช้
"skip"สำหรับงานส่วนใหญ่เพื่อไม่ให้รันซ้อน - ใช้
"queue"เฉพาะเมื่อทุกครั้งสำคัญมาก
3. จัดการเครดิตอย่างรอบคอบ
- ตั้ง
max_executions_per_dayสำหรับงานแพง - ดู
min_credits_requiredในรายละเอียดงาน (ประมาณการจากเซิร์ฟเวอร์) - ติดตามการใช้เครดิตในประวัติการรัน
4. ตรวจสุขภาพงาน
- ตรวจ
consecutive_failuresเป็นประจำ - ทบทวนประวัติการรันเพื่อหาแพตเทิร์น
- ตั้ง webhook แจ้งเมื่อล้มเหลว
5. ใช้ชื่อและแท็กที่อธิบายได้
- ตั้งชื่องานชัดเจน
- เพิ่มแท็กเพื่อกรองและจัดกลุ่ม
- ใส่เมตadata ที่เกี่ยวข้องเพื่อติดตาม
ข้อจำกัด
| Item | Limit |
|---|---|
| ความยาวชื่องาน | 1–255 ตัวอักษร |
| ช่วงขั้นต่ำ | 1 นาที |
| โหมด concurrency | skip, queue |
| ขนาดเพย์โหลดงาน | 100KB |
| รูปแบบ cron | มาตรฐาน 5 ฟิลด์ |
แก้ปัญหา
งานไม่รัน
ตรวจสอบ:
- งาน active? (
is_active: true) - งานถูกหยุด? (
is_paused: false) - นิพจน์ cron ถูกต้อง?
- เครดิตพอ?
อัตราล้มเหลวสูง
สาเหตุที่เป็นไปได้:
- เว็บเป้าหมายบล็อกคำขอ
- URL ในเพย์โหลดไม่ถูกต้อง
- timeout ไม่พอ
- ปัญหาเครือข่าย
แนวทาง:
- เพิ่มดีเลย์ด้วย
wait_for - ลองเครื่องมืออื่น (Playwright สำหรับเว็บไดนามิก)
- เพิ่ม timeout
- ดูข้อความข้อผิดพลาดในประวัติการรัน
เครดิตหมดเร็ว
แนวทาง:
- ลดความถี่การรัน
- ตั้ง
max_executions_per_day - ใช้เพย์โหลดต้นทุนต่ำ (หน้า/ผลน้อยลง รูปแบบเบาลง)
- ทบทวนประวัติเพื่อหาการรันที่แพง
เอกสารที่เกี่ยวข้อง
- Webhooks — การแจ้งเหตุการณ์สำหรับงานตามกำหนดเวลา
- Scrape API — การตั้งค่างานดึงข้อมูล
- Crawl API — การตั้งค่างานครอล