استخراج روابط PDF
من سبعة عناصر تفاعلية في صفحات ملف PDF تحصل على الروابط الأربعة الحقيقية، كل رابط مع رقم صفحته، وتُستبعد الملاحظات والتظليل والقفزات الداخلية. والرابط المكرر في ثلاث صفحات يظهر ثلاث مرات. مجاني في متصفحك.
- مجاني
- يعمل في متصفحك
- دون تسجيل
- بياناتك لا تغادر جهازك
شغّل الأداة مجانًا
تعمل هذه الأداة داخل متصفحك — مجانًا، ولا تُرسل بياناتك إلى أي خادم
يقوم مستخرج روابط PDF بقراءة قائمة التعليقات التوضيحية لكل صفحة من ملف PDF — وهي بالضبط ما تعيده مكتبة قراءة مثل pdf.js من getAnnotations — ويعيد كل رابط تشعبي يجده، مع رقم صفحته وعنوان URL المقصود. إنها الخطوة الناقصة بين «لديّ التعليقات التوضيحية» و«أعرف إلى أين يشير هذا المستند»: مرور واحد حتمي، بلا عرض للصفحات، وبلا OCR، وبلا تخمين. تُستبعد الروابط الداخلية البحتة والتعليقات التي ليست روابط، بحيث تحصل في النهاية على قائمة نظيفة ومرتّبة بالمراجع الخارجية التي يتضمنها المستند، جاهزة للتدقيق أو لقائمة بداية لزاحف أو لفحص امتثال.
لماذا التعليقات التوضيحية وليس النص الخام
إن البحث عن الروابط بمسح النص المستخرج غير موثوق: فعنوان URL الظاهر في النص قد لا يكون قابلًا للنقر، وقد يعرض الرابط القابل للنقر نصًا تثبيتيًا لا يشبه وجهته إطلاقًا. إن المصدر الموثوق لاستخراج الروابط من PDF هو طبقة التعليقات التوضيحية. تخزّن قارئات PDF العناصر التفاعلية على شكل تعليقات مرتبطة بصفحة، وتوجد الروابط التشعبية هناك كمدخلات من النوع الفرعي Link مع URI.
تأخذ هذه القدرة تلك القائمة مدخلًا — سجلًا واحدًا لكل تعليق مع رقم صفحته ونوعه الفرعي وURI الاختياري — وتصفّيها حتى الروابط التشعبية الصادرة الفعلية. ولأن رقم الصفحة يرافق كل تعليق، فإن كل نتيجة تخبرك بدقة أين يقع الرابط في المستند، وهذا ما يجعل المخرجات صالحة للمراجعات والتدقيقات بدلًا من مجرد قائمة عناوين URL.
ما الذي يحتفظ به المستخرج وما الذي يستبعده
إن المرشّح صارم عن قصد. لا تُؤخذ في الحسبان إلا التعليقات التي نوعها الفرعي Link؛ أما الملاحظات والتمييزات اللونية وعناصر النماذج وكل أنواع التعليقات الأخرى فتُتخطى. ومن بين تعليقات Link لا تبقى إلا تلك التي تحمل URI غير فارغ: فتعليق الرابط بلا URI يكون عادةً قفزة داخلية إلى صفحة أخرى، أي تنقلًا داخل المستند لا رابطًا تشعبيًا إلى وجهة خارجية، لذا يُستبعد.
تُزال المسافات المحيطة بعناوين URI لكنها تُعاد حرفيًا فيما عدا ذلك: بلا إعادة كتابة، وبلا حلّ، وبلا إزالة تكرار. إذا ظهر عنوان URL نفسه في ثلاث صفحات، تحصل على ثلاثة مدخلات، لأن ظهوره ثلاث مرات هو بحد ذاته معلومة. تُرتَّب المخرجات تمامًا كما تصل التعليقات، وهو ما يعني عمليًا ترتيب المستند.
وقد يظهر عنوان URL نفسه عدة مرات بشكل مشروع في مستند طويل — في التذييل المتكرر، وفي قائمة المراجع، وفي صفحة الاتصال — ودمج تلك التكرارات يمحو الفرق بين استشهاد عابر ومرجع منهجي، لذا يحتفظ المستخرج بها جميعًا ويترك للمتصل أن يقرر ما يجمعه لاحقًا.
أين تتموضع في خط المعالجة
التدفق المعتاد هو: افتح ملف PDF بمكتبة قراءة، واجمع التعليقات صفحة بصفحة، وسوِّها في قائمة السجلات التي تتوقعها هذه القدرة، ثم أرسلها. تحصل في المقابل على عدد ومصفوفة من أزواج {page, url}. تستخدمها الفرق لجرد المراجع الصادرة في العقود والتقارير قبل النشر، ولبناء قائمة البداية لجولة فحص الروابط، أو للتأكد من أن مستندًا منقّحًا لم يعد يشير إلى حيث لا ينبغي.
تُعامل قائمة التعليقات الفارغة خطأً لا نتيجة فارغة، لأن القائمة الفارغة تعني دائمًا تقريبًا أن خطوة الاستخراج السابقة فشلت أو أن الملف لم يكن له طبقة تعليقات أصلًا — وإعادة صفر رابط بصمت ستحجب ذلك.
حالات الاستخدام
دقّق المراجع الصادرة قبل النشر
اجرد كل رابط تشعبي في تقرير أو عقد مع أرقام الصفحات، ليتمكن المراجعون من التأكد من أن كل وجهة مقصودة وصحيحة.
زوّد فحص الروابط المعطلة
مرّر عناوين URL المستخرجة إلى فاحص روابط لاكتشاف الوجهات الميتة في مستند يوشك عملاؤك على تنزيله.
تحقق من مستند منقّح
تأكد من أن النسخة المنشورة من ملف PDF لم تعد ترتبط بعناوين URL داخلية للاختبار أو لشركاء كان يجب حذفها.
الأسئلة الشائعة
كم التكلفة؟
ويمكن أيضًا تشغيلها مجانًا في متصفحك على هذه الصفحة.
ما المدخل المتوقع؟
قائمة تعليقات مسوّاة: سجل واحد لكل تعليق مع رقم صفحته الذي يبدأ من 1 ونوعه الفرعي وURI للروابط. تنتج مكتبات القراءة مثل pdf.js ذلك من getAnnotations مع خطوة تحويل بسيطة.
لماذا أحصل على خطأ بدلًا من قائمة فارغة؟
المصفوفة الفارغة من التعليقات تعني أن الاستخراج السابق فشل أو أن ملف PDF بلا طبقة تعليقات.
هل تُشمل القفزات الداخلية بين الصفحات؟
لا. تعليقات الروابط بلا URI هي وجهات داخلية ضمن المستند، لا روابط تشعبية صادرة، وتُتخطى.
هل تُزال تكرارات عناوين URL؟
لا. إذا كان عنوان URL نفسه مرتبطًا في ثلاث صفحات تحصل على ثلاثة مدخلات، لأن كل ظهور يحمل رقم صفحته الخاص وهذا التكرار بحد ذاته معلومة مفيدة.
هل يجري جلب عناوين URL أو التحقق منها؟
لا. الاستخراج محلي وحتمي تمامًا؛ ولا تُجرى أي طلبات شبكة نحو الوجهات.
أدوات ذات صلة
للمطوّرين — الوصول عبر API
كل ما في هذه الصفحة متاح برمجيًا. هذا القسم موجّه للفرق التقنية التي تريد ربط الأداة بأنظمتها الخاصة؛ بقية المستخدمين يمكنهم استخدام الأداة أعلاه مباشرة دون الحاجة لقراءة ما يلي.
الـEndpoint
صادِق على طلبك بترويسة Bearer، وأرسل طلب POST واحدًا لتدخل مهمتك قائمة التنفيذ فورًا؛ ثم تستلم النتيجة عبر webhook أو رابط موقّع.
استدعِ الخدمة من بيئتك
curl -X POST https://api.kit.forhosting.com/pdf/extract-links \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"annotations":[{"page":1,"subtype":"Link","uri":"https://example.com/docs"},{"page":1,"subtype":"Text","uri":null},{"page":3,"subtype":"Link","uri":"https://example.com/contact"}]}'const res = await fetch("https://api.kit.forhosting.com/pdf/extract-links", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"annotations": [
{
"page": 1,
"subtype": "Link",
"uri": "https://example.com/docs"
},
{
"page": 1,
"subtype": "Text",
"uri": null
},
{
"page": 3,
"subtype": "Link",
"uri": "https://example.com/contact"
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/extract-links",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"annotations": [
{
"page": 1,
"subtype": "Link",
"uri": "https://example.com/docs"
},
{
"page": 1,
"subtype": "Text",
"uri": null
},
{
"page": 3,
"subtype": "Link",
"uri": "https://example.com/contact"
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/extract-links", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"annotations":[{"page":1,"subtype":"Link","uri":"https://example.com/docs"},{"page":1,"subtype":"Text","uri":null},{"page":3,"subtype":"Link","uri":"https://example.com/contact"}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"annotations":[{"page":1,"subtype":"Link","uri":"https://example.com/docs"},{"page":1,"subtype":"Text","uri":null},{"page":3,"subtype":"Link","uri":"https://example.com/contact"}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/extract-links", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)مثال على الطلب
{
"annotations": [
{
"page": 1,
"subtype": "Link",
"uri": "https://example.com/docs"
},
{
"page": 1,
"subtype": "Text",
"uri": null
},
{
"page": 3,
"subtype": "Link",
"uri": "https://example.com/contact"
}
]
}مثال على الاستجابة
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.extract_links",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}الواجهة غير متزامنة: تستلم task_id فور الإرسال، ويمكنك الاستعلام عن الحالة بمعدل طلب واحد في الثانية.
الأسعار
السعر معلن كما تراه: لا tokens ولا نظام نقاط؛ وإن فشلت المهمة فلن تُحاسَب عليها.
الحدود
max_mb | 1 |
max_annotations | 50000 |
الأخطاء
| HTTP | الرمز | المعنى |
|---|---|---|
401 | unauthorized | مفتاح الوصول مفقود أو غير صالح؛ تحقق من ترويسة Bearer في طلبك. |
402 | insufficient_balance | رصيدك لا يكفي لتنفيذ هذه المهمة؛ أعد شحن الرصيد ثم أعد المحاولة. |
404 | unknown_type | نوع المهمة المطلوب غير موجود في الكتالوج — راجع الاسم المرسل في الطلب. |
429 | rate_limited | تجاوزت الحد المسموح من الطلبات؛ انتظر قليلًا ثم أعد المحاولة. |
ملاحظات تقنية
لماذا التعليقات التوضيحية وليس النص الخام
كما يتحقق العقد من كل سجل أثناء المعالجة: فرقم صفحة مفقود أو صفحة غير صحيحة العدد أو نوع فرعي غائب يوقف النداء بخطأ invalid_input واضح، بدلًا من إنتاج إجابة جزئية صامتة قد تميل إلى الوثوق بها.
أين تتموضع في خط المعالجة
الشيفرة نفسها تعمل مجانًا في متصفحك على هذه الصفحة، فيمكنك التحقق من حمولة بلصقها ولا تدفع إلا عندما تؤتمت النداء.