> ## Documentation Index
> Fetch the complete documentation index at: https://docs.acedata.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# WebExtrator دليل تكامل واجهة برمجة تطبيقات عرض صفحات الويب

> WebExtrator Web Render & Extract API guide - Ace Data Cloud

`POST https://api.acedata.cloud/webextrator/render`

واجهة برمجة تطبيقات عرض صفحات الويب WebExtrator هي خدمة عرض صفحات ويب تعتمد على Chromium بدون رأس. عند إعطائها عنوان URL، تعيد HTML مكتمل العرض (بما في ذلك المحتوى الذي تم حقنه بواسطة JS)، نص عادي، عنوان الصفحة، والعنوان النهائي.

Render هو واجهة WebExtrator الأساسية. إذا كنت بحاجة إلى نتائج استخراج **منظمة** (نص المقال، أسعار المنتجات، مكونات الوصفات ...)، يرجى استخدام
[`/webextrator/extract`](development_webextrator_extract) — حيث يتم تشغيل مجموعة كاملة من خطوط استخراج نوعية على نفس أساس العرض.

## عملية التقديم

لاستخدام صفحة خدمة WebExtrator، يجب أولاً الذهاب إلى [لوحة تحكم Ace Data Cloud](https://platform.acedata.cloud/console/applications) للحصول على رمز API الخاص بك، احتفظ به للاستخدام لاحقًا.

![](https://cdn.acedata.cloud/5hmkdg.jpg)

إذا لم تكن قد قمت بتسجيل الدخول أو التسجيل، سيتم تحويلك تلقائيًا إلى صفحة تسجيل الدخول لدعوتك للتسجيل وتسجيل الدخول، وبعد الانتهاء، سيتم إرجاعك تلقائيًا إلى الصفحة الحالية.

**يمكن استخدام رمز API واحد لاستدعاء جميع خدمات المنصة، دون الحاجة لتقديم طلب منفصل لكل خدمة.** سيتم منحك رصيد مجاني عند الطلب الأول، يمكنك تجربته مجانًا؛ عند نفاد الرصيد، يمكنك إعادة شحن الرصيد العام في [لوحة التحكم](https://platform.acedata.cloud/console/coin).

> 📘 الوثائق الكاملة: [صفحة خدمة WebExtrator →](https://platform.acedata.cloud/service/webextrator)

## المصادقة

تستخدم جميع واجهات WebExtrator مصادقة Bearer Token القياسية:

```
Authorization: Bearer YOUR_API_KEY
Content-Type:  application/json
```

## معلمات الطلب

| الحقل               | النوع     | مطلوب | الافتراضي                  | الشرح                                                                                                               |
| ------------------- | --------- | :---: | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `url`               | string    |   ✅   | —                          | عنوان URL للصفحة التي يجب عرضها، يجب أن يكون `http(s)://`.                                                          |
| `user_agent`        | string    |   ❌   | مجموعة UA المدمجة تتناوب   | User-Agent مخصص.                                                                                                    |
| `timeout`           | number    |   ❌   | `30`                       | مهلة التنقل لمرة واحدة (**ثواني**).                                                                                 |
| `wait_until`        | enum      |   ❌   | `networkidle`              | حدث تحميل مكتمل: `load` / `domcontentloaded` / `networkidle` / `commit`.                                            |
| `delay`             | number    |   ❌   | `0`                        | **عدد الثواني الإضافية** بعد تفعيل `wait_until` (لإعادة عرض SPA).                                                   |
| `wait_for_selector` | string    |   ❌   | —                          | الانتظار حتى ظهور محدد CSS، أكثر استقرارًا من `networkidle`.                                                        |
| `block_resources`   | string\[] |   ❌   | `["image","font","media"]` | أنواع الموارد المحجوبة، اختيارية: `image` / `font` / `media` / `stylesheet` / `xhr` / `fetch`.                      |
| `headers`           | object    |   ❌   | —                          | رؤوس HTTP إضافية (مثل `{"Accept-Language": "en-US"}`).                                                              |
| `cookies`           | array     |   ❌   | —                          | ملفات تعريف الارتباط التي يتم حقنها قبل التنقل، الهيكل كما هو موضح أدناه.                                           |
| `callback_url`      | string    |   ❌   | —                          | عنوان الاسترجاع في وضع غير المتزامن، حيث يقوم النظام بإرسال النتائج الكاملة إلى هذا العنوان عند الانتهاء من المهمة. |
| `bypass_cache`      | boolean   |   ❌   | `false`                    | تخطي قراءة ذاكرة التخزين المؤقت Redis (لكن لا يزال سيكتب النتيجة الحالية إلى الذاكرة المؤقتة).                      |
| `cache_ttl_seconds` | number    |   ❌   | `3600`                     | تخصيص TTL للذاكرة المؤقتة لهذه الكتابة، إرسال `0` يعني عدم تخزين الاستجابة الحالية.                                 |
| `async`             | boolean   |   ❌   | `false`                    | تعيينها إلى `true` لإرجاع `task_id` على الفور، واسترجاع النتائج عبر `callback_url` أو واجهة برمجة التطبيقات Tasks.  |

> تستخدم عقود المنصة **snake\_case** بشكل موحد. تدعم خدمات العرض الداخلية camelCase، لكن جميع الاستدعاءات الخارجية تستخدم snake\_case.

### هيكل ملفات تعريف الارتباط

```json theme={null}
{
  "name":      "string",
  "value":     "string",
  "domain":    "string",
  "path":      "/",
  "expires":   1735689600,
  "httpOnly":  false,
  "secure":    true,
  "sameSite":  "Lax"
}
```

## الاستجابة المتزامنة

```json theme={null}
{
  "success": true,
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "trace_id": "550e8400-e29b-41d4-a716-446655440001",
  "started_at": "2026-05-02T10:30:00.123Z",
  "finished_at": "2026-05-02T10:30:01.234Z",
  "elapsed": 1.111,
  "data": {
    "kind": "render",
    "url": "https://example.com",
    "finalUrl": "https://example.com/",
    "title": "Example Domain",
    "status": 200,
    "html": "<!DOCTYPE html><html>...</html>",
    "text": "Example Domain\nThis domain is for use in illustrative examples...",
    "userAgent": "Mozilla/5.0 ...",
    "elapsedMs": 1108
  }
}
```

| الحقل                | النوع          | الشرح                                                                             |
| -------------------- | -------------- | --------------------------------------------------------------------------------- |
| `data.kind`          | string         | ثابت `"render"`。                                                                  |
| `data.url`           | string         | عنوان URL الذي قدمته.                                                             |
| `data.finalUrl`      | string         | عنوان URL النهائي بعد اتباع إعادة التوجيه.                                        |
| `data.title`         | string         | `document.title` بعد العرض.                                                       |
| `data.status`        | number \| null | رمز حالة HTTP للتنقل الرئيسي.                                                     |
| `data.html`          | string         | HTML الكامل بعد العرض.                                                            |
| `data.text`          | string         | لقطة `document.body.innerText` (إذا كنت بحاجة إلى نص أكثر نظافة، استخدم Extract). |
| `data.userAgent`     | string         | UA المستخدم فعليًا.                                                               |
| `data.elapsedMs`     | number         | الوقت المستغرق فقط في عرض المتصفح.                                                |
| `data.cached`        | boolean?       | يكون `true` عند الوصول إلى الذاكرة المؤقتة.                                       |
| `data.cacheStoredAt` | number?        | الطابع الزمني بالمللي ثانية لكتابة إدخال الذاكرة المؤقتة لأول مرة.                |

## الاستجابة غير المتزامنة

عند `async=true` (أو تقديم `callback_url`) يتم إرجاعها على الفور (HTTP 200):

```json theme={null}
{
  "success": true,
  "task_id": "550e8400-...",
  "trace_id": "6ba7b810-...",
  "started_at": "2026-05-02T10:30:00.123Z"
}
```

سيتم دفع النتائج عبر `POST` إلى `callback_url` (إذا تم تكوينه)، أو من خلال
[`/webextrator/tasks`](development_webextrator_tasks) للاستعلام النشط.

### هيكل الاسترجاع

تقوم المنصة بإرسال `POST` بنفس envelope **تمامًا** مثل الوضع المتزامن إلى `callback_url`،
`Content-Type: application/json`. تعتبر أي استجابة `2xx` تأكيدًا؛ بينما سيتم إعادة المحاولة مع تراجع أسي لمدة حوالي 5 دقائق في حالة `5xx`.

## استجابة الخطأ

| HTTP | `error.code`     | المعنى                                                                                               |
| ---- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| 400  | `bad_request`    | لم يمر جسم الطلب عبر تحقق Zod (يفتقر إلى `url`، نوع غير صحيح …).                                     |
| 401  | `unauthorized`   | مفقود أو غير صالح `Authorization: Bearer …`.                                                         |
| 402  | (x402)           | رصيد المنصة غير كاف، يرجى إعادة x402 طلب الدفع envelope.                                             |
| 408  | `timeout`        | تجاوز التنقل `timeout`.                                                                              |
| 429  | `queue_busy`     | قائمة الانتظار مشغولة، يرجى المحاولة مرة أخرى أو استخدام `async=true`.                               |
| 500  | `internal_error` | استثناء غير معالج من جانب الخادم (مثل تعطل المتصفح)، يقوم العامل بإعادة المحاولة تلقائيًا مرة واحدة. |

هيكل الخطأ:

```json theme={null}
{
  "success": false,
  "task_id": "...",
  "trace_id": "...",
  "started_at": "...",
  "finished_at": "...",
  "elapsed": 0.012,
  "error": { "code": "bad_request", "message": "url: Invalid url" }
}
```

## مثال

### cURL

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/render \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "wait_until": "networkidle",
    "block_resources": ["image", "media", "font"]
  }'
```

### بايثون (requests)

```python theme={null}
import os, requests

API_KEY = os.environ["ACEDATA_API_KEY"]

resp = requests.post(
    "https://api.acedata.cloud/webextrator/render",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "url": "https://example.com",
        "wait_until": "networkidle",
        "block_resources": ["image", "media", "font"],
    },
    timeout=60,
)
resp.raise_for_status()
data = resp.json()["data"]
print(data["title"], data["status"], len(data["html"]))
```

### Node.js (fetch)

```js theme={null}
const apiKey = process.env.ACEDATA_API_KEY;

const res = await fetch('https://api.acedata.cloud/webextrator/render', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com',
    wait_until: 'networkidle',
    block_resources: ['image', 'media', 'font'],
  }),
});
const { data } = await res.json();
console.log(data.title, data.status, data.html.length);
```

### غير متزامن + رد الاتصال

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/render \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "async": true,
    "callback_url": "https://your-app.example.com/hooks/webextrator"
  }'
```

يرجع على الفور `{ "success": true, "task_id": "...", "trace_id": "...", "started_at": "..." }`؛
عند الانتهاء من المهمة، ستقوم المنصة بإرسال POST بالنتيجة الكاملة إلى `callback_url` الخاص بك.

### تجاوز التخزين المؤقت بالقوة

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/render \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "bypass_cache": true
  }'
```

## نصائح ومشاكل

* **اختيار `wait_until` الصحيح مهم جدًا.** `networkidle` هو الأكثر استقرارًا ولكنه الأبطأ؛ `domcontentloaded`
  سريع ولكنه قد يفوت المحتوى المحقون بشكل غير متزامن؛ `load` مناسب للصفحات الثابتة التقليدية.
* **تجاهل مفتاح التخزين المؤقت لـ `async`.** الطلبات المتزامنة وغير المتزامنة لنفس URL تضرب نفس إدخال التخزين المؤقت،
  التبديل بحرية لن يؤدي إلى الفشل.
* **تجاهل مفتاح التخزين المؤقت لـ `bypass_cache` و `cache_ttl_seconds`.** هذان مفتاحان للتشغيل،
  لا يؤثران على محتوى الاستجابة.
* **تخزين `cookies` و `headers` في دلو منفصل.** تخصيص هذين سيؤدي إلى فشل الضرب الأول لنفس المجموعة.
* **تجاوز SPA غالبًا ما يتجاوز 30 ثانية الافتراضية.** يُنصح بـ `timeout: 60`، `wait_until: "domcontentloaded"`، `delay: 4`، مع استخدام `wait_for_selector` لانتظار العناصر التي تهمك حقًا.
* **`block_resources` هو أسرع طريق لتقليل التأخير.** تم حظر الصور / الخطوط / الوسائط بشكل افتراضي؛
  إذا كنت تستخرج دون الاعتماد على تخطيط CSS، يمكنك إضافة `stylesheet` لتكون أسرع.
