كيفية استخدام بروكسي مع HttpClient في C#: الأنماط والحلول

آخر تحديث في June 1, 2026
كيفية استخدام بروكسي مع HttpClient في C#: الأنماط والحلول
ملخص بالذكاء الاصطناعي
اضبط البروكسيات في C# باستخدام HttpClient عبر تعيين بيانات الاعتماد على كائن WebProxy. اتبع هذه الأنماط لتدوير بروكسي احترافي في 2026.

الأسبوع الماضي قضيت وقتًا طويلًا ومحرجًا وأنا أحدّق في ردّ 407 Proxy Authentication Required وأنا مقتنع أن مزوّد البروكسي عندي فيه مشكلة. وفي النهاية اتضح أنني وضعت بيانات الاعتماد في الخاصية الغلط — إصلاح من سطرين أخذ مني ساعتين حتى أكتشفه. إذا كان هذا السيناريو مألوفًا لك، فهذا الدليل لك.

إعداد البروكسي مع HttpClient في C# من المواضيع التي تبدو بسيطة على الورق، لكن التفاصيل في بيئة الإنتاج — مثل استنزاف المقابس، وعدم تطابق إصدار SOCKS5، واللخبطة في بيانات الاعتماد — تسرق وقتًا حقيقيًا.

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

مستوى الصعوبة: مبتدئ إلى متوسط
الوقت المطلوب: حوالي 15 دقيقة للمتابعة، وأكثر إذا كنت ستطبّق أنماط التدوير في بيئة إنتاج
ما ستحتاجه: ‎.NET 6+ SDK (لدعم SOCKS5 وميزات الـ handler الحديثة؛ كما يعمل ‎.NET Framework 4.x لأمثلة بروكسي HTTP الأساسية)، ومحرر كود، ونقطة بروكسي واحدة على الأقل للاختبار

ما هو HttpClient ولماذا يحتاج إلى بروكسي؟

csharp-app-httpclient-proxy-flow.webp

HttpClient هو الصنف المدمج في .NET داخل System.Net.Http لإرسال طلبات HTTP واستقبال الردود. وهو يدعم async/await، والرؤوس المخصصة، وCancellationToken، والإعداد عبر الـ handlers. وتصفه Microsoft بأنه صنف لإرسال طلبات HTTP واستقبال استجابات HTTP من مورد محدد بواسطة URI.

خادم البروكسي هو وسيط بين تطبيقك والموقع المستهدف. عندما تمرّر الحركة عبر بروكسي، يرى الموقع عنوان IP الخاص بالبروكسي بدلًا من عنوانك.

HttpClient نفسه لا يملك خاصية Proxy. إعداد التوجيه عبر البروكسي يتم على الـ handler الأساسي — إما HttpClientHandler أو SocketsHttpHandler — والذي يقبل كائنًا من WebProxy. النموذج الذهني يكون كالتالي:

[تطبيق C# الخاص بك] → [HttpClient + Handler] → [خادم البروكسي] → [الموقع المستهدف]

لذلك، فكرة “تغيير البروكسي على HttpClient مباشرة” ليست مجرد تعيين خاصية، بل هي مسألة تصميم كاملة. سنفصل أكثر في جزء التدوير.

جرّب Thunderbit لاستخراج البيانات بسهولة أكبر

لماذا تستخدم بروكسي مع HttpClient في C#؟

المطورون يوجّهون حركة HttpClient عبر البروكسيات لأسباب متكررة، ونوع البروكسي المناسب يعتمد على المهمة نفسها.

  • تجنب حظر IP وحدود المعدل: مهم جدًا لكشط الويب، وتوليد العملاء المحتملين، أو مراقبة الأسعار على نطاق واسع. أي عنوان IP واحد يهاجم موقعًا بسرعة غالبًا سيتحظر.
  • تجاوز القيود الجغرافية: الوصول إلى واجهات API أو محتوى مقيد بمنطقة معينة عبر تمرير الحركة من دول محددة.
  • إخفاء عنوانك الأصلي: إضافة طبقة خصوصية عند جمع البيانات الحساسة أو تنفيذ بحث تنافسي.
  • متطلبات مؤسسية أو امتثالية: كثير من الشركات تشترط مرور الحركة الخارجية عبر بوابة مركزية لأغراض التسجيل والحوكمة.
  • الاختبار وضمان الجودة: محاكاة طلبات من مواقع أو ظروف شبكة مختلفة من دون نشر بنية تحتية فعلية في تلك المناطق.
حالة الاستخدامنوع البروكسي المعتادلماذا يناسب
كشط الويب على نطاق واسعبروكسيات سكنية متغيرةتنوع أكبر في عناوين IP وصعوبة أعلى على أنظمة مكافحة البوت
مراقبة أسعار التجارة الإلكترونيةبروكسيات سكنية أو بروكسيات مراكز بيانات موجّهة جغرافيًافحص الأسعار والمخزون بحسب المنطقة
الوصول إلى API عبر بوابة ثابتةبروكسي مراكز بيانات أو بروكسي مؤسسيIP متوقع لإدراج السماح، وتكلفة أقل
الامتثال المؤسسيبروكسي النظام، بروكسي PAC، أو بروكسي شركة بمصادقةتسجيل مركزي وتحكم في الحركة الخارجة
اختبار QA والتعريبمجموعة بروكسيات خاصة بدول معينةمحاكاة وصول المستخدمين الحقيقيين من المناطق المستهدفة

وعادةً، استخدام البروكسي يتدرج بشكل منطقي. تبدأ ببروكسي ثابت واحد للتأكد من أن التوجيه شغال. ثم ينتقل كاشف الإنتاج إلى مجموعة بروكسيات، مع ربط الطلبات بالبروكسيات حسب النطاق المستهدف أو الموقع الجغرافي أو معدل الفشل. أما الفرق الناضجة فتتجه غالبًا إلى بوابة بروكسي مُدارة تتولى التدوير وإعادة المحاولة وثبات الجلسة خلف نقطة نهاية واحدة.

تدوير البروكسي ليس عصا سحرية. إذا كان الموقع المستهدف يحظر السلوك المشبوه، فمجرد تغيير عناوين IP لن يفيد كثيرًا إلا إذا تمت أيضًا إدارة معدل الطلبات والرؤوس والكوكيز وبصمة TLS بعناية.

ما الذي تدعمه كل نسخة من .NET: جدول توافق سريع

نسخ مقطع بروكسي من تدوينة ولصقه في إطار مستهدف غير مناسب هو من أكبر أسباب الأعطال الصامتة. أهم خط فاصل هنا هو بين ‎.NET Framework 4.x و .NET الحديث (‎.NET 6+). هذا ما يعمل وأين:

.net-version-comparison.webp

الميزة‎.NET Framework 4.x‎.NET 6‎.NET 7‎.NET 8–9
WebProxy + HttpClientHandlerنعمنعمنعمنعم
SOCKS5 عبر WebProxy("socks5://...")لانعم (أُضيف في ‎.NET 6)نعمنعم
SocketsHttpHandler (الـ handler الافتراضي)لانعمنعمنعم
HttpClient.DefaultProxy الثابتلانعمنعمنعم
PooledConnectionLifetimeلانعمنعمنعم

إذا كنت تستهدف ‎.NET Framework 4.x، فالتزم ببروكسيات HTTP/HTTPS مع HttpClientHandler وWebProxy. أما SOCKS5 والتحكمات الحديثة في التجميع فتحتاج إلى ‎.NET 6 أو أحدث.

في نقطة مهمة جدًا: HttpClient.DefaultProxy خاصية ثابتة في ‎.NET الحديث. إذا تم ضبطها في كود بدء التشغيل المشترك أو ورثتها من متغيرات البيئة مثل HTTPS_PROXY أو HTTP_PROXY, فكل كائن HttpClient سيستخدمها ما لم تلغها صراحةً على مستوى الـ handler. وفي بيئات الحاويات، هذا سبب شائع جدًا لحالة “ليش العميل يستخدم بروكسي أنا أصلًا ما ضبطته؟”.

الخطوة 1: أنشئ مشروع Console جديدًا بـ C#

افتح الطرفية وأنشئ مشروعًا جديدًا:

dotnet new console -n ProxyHttpClientDemo
cd ProxyHttpClientDemo

تحقق من إصدار الـ SDK عبر dotnet --version. الأمثلة في هذا الدليل تستهدف ‎.NET 6+ لتغطية كامل الميزات. إذا كنت تريد أحدث إصدار LTS، فحمّله من صفحة تنزيل Microsoft.

افتح Program.cs في محررك. هناك سيبدأ كل شيء.

الخطوة 2: نفّذ طلب HTTP أساسيًا بدون بروكسي

قبل إعداد البروكسي، حدّد عنوان IP الحقيقي الخارج من شبكتك. بهذه الطريقة، بعد تفعيل البروكسي، تقدر تتأكد أن الـ IP تغيّر فعلًا.

using System.Net.Http;

using var client = new HttpClient();
var ip = await client.GetStringAsync("https://api.ipify.org/");
Console.WriteLine($"Direct IP: {ip}");

شغّل الكود. يجب أن ترى عنوان IP العام الحالي لديك، مثل:

Direct IP: 203.0.113.10

احتفظ بهذه القيمة في بالك. بعد الخطوة التالية، يجب أن تختلف.

الخطوة 3: اضبط WebProxy مع HttpClientHandler

النمط الكلاسيكي يتكوّن من ثلاثة كائنات: WebProxy، وhandler، والعميل.

using System.Net;
using System.Net.Http;

var proxy = new WebProxy("http://proxy.example.com:8080")
{
    BypassProxyOnLocal = false
};

var handler = new HttpClientHandler
{
    Proxy = proxy,
    UseProxy = true,
    UseDefaultCredentials = false
};

using var client = new HttpClient(handler);
var ip = await client.GetStringAsync("https://api.ipify.org/");
Console.WriteLine($"Proxy IP: {ip}");

استبدل proxy.example.com:8080 بنقطة نهاية البروكسي الفعلية عندك. إذا كان كل شيء مضبوطًا صح، يجب أن يطابق عنوان IP الناتج عنوان الخروج الخاص بالبروكسي، وليس عنوانك الحقيقي.

الخصائص الأساسية التي لازم تفهمها:

  • Proxy — كائن IWebProxy الذي يستخدمه الـ handler للتوجيه.
  • UseProxy = true — يخبر الـ handler أن يستخدم البروكسي المهيأ فعلًا. (ممكن يبدو بديهيًا، لكن نسيانه يضيع وقتًا طويلًا جدًا.)
  • BypassProxyOnLocal = false — يمنع الـ handler من تجاوز البروكسي للوجهات التي تبدو “محلية”.
  • UseDefaultCredentials — يتحكم فيما إذا كان الـ handler يرسل بيانات اعتماد Windows الافتراضية. وهذا ليس نفسه اسم المستخدم/كلمة المرور الخاصة بالبروكسي.

proxy-ip-flowchart.webp

الخطوة 4: أضف مصادقة البروكسي باستخدام NetworkCredential

كثير من مزوّدي البروكسي المدفوع يطلبون بيانات اعتماد. النمط الصحيح هو ضبطها على كائن WebProxy نفسه:

using System.Net;
using System.Net.Http;

var proxy = new WebProxy("http://proxy.example.com:8080")
{
    Credentials = new NetworkCredential("proxy-user", "proxy-password")
};

var handler = new HttpClientHandler
{
    Proxy = proxy,
    UseProxy = true
};

using var client = new HttpClient(handler);
var ip = await client.GetStringAsync("https://api.ipify.org/");
Console.WriteLine($"Authenticated proxy IP: {ip}");

كثير من المزوّدين يعطونك صيغة URL مثل http://username:password@host:port. لكن في كود .NET الأفضل استخدام NetworkCredential بدلًا من وضع بيانات الاعتماد داخل سلسلة URI. هذا يتفادى مشاكل الهروب مع المحارف الخاصة في كلمات المرور، ويخلي الفرق بين الـ URI وبيانات الاعتماد واضحًا.

سأشرح أكثر خطأ المصادقة الشائع — ولماذا يسبب أخطاء 407 — في قسم مخصص أدناه.

الخطوة 5: صدّر أو استخدم بيانات الاستجابة

في أي شيء يتجاوز فحص IP سريعًا، تعامل مع الاستجابة بشكل صحيح:

using var response = await client.GetAsync("https://example.com/api/products");

if (!response.IsSuccessStatusCode)
{
    Console.WriteLine($"فشل الطلب: {(int)response.StatusCode} {response.ReasonPhrase}");
    return;
}

var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);

في تدفقات الكشط، الطلب عبر البروكسي هو فقط طبقة النقل. ما زلت بحاجة إلى التحليل، والتطبيع، وإزالة التكرار، وإعادة المحاولة، والتصدير إلى Excel أو Google Sheets أو قواعد البيانات أو وجهات أخرى. أدوات مثل Thunderbit يمكنها أتمتة خطوات الاستخراج والتصدير — إذ يتولى امتداد Chrome استخراج البيانات المهيكلة والتصدير المجاني إلى Google Sheets أو Excel أو Airtable أو Notion من دون الحاجة إلى كتابة كود تحليل.

صدّر البيانات المستخرجة إلى Excel أو Sheets أو Airtable أو Notion Get Started Free

بيانات اعتماد البروكسي مقابل بيانات اعتماد الخادم: الخطأ الذي يسبب أخطاء 407

proxy-authentication-diagram.webp

شفت هذا الخطأ في نقاشات Stack Overflow، وفي منشورات Microsoft Q&A، وبصراحة في كودي أنا أيضًا.

الفرق بسيط لكنه سهل الالتباس:

  • بيانات اعتماد البروكسي تصادقك لدى خادم البروكسي نفسه.
  • بيانات اعتماد الخادم تصادقك لدى الخادم/الوجهة النهائية.

في HttpClientHandler، يوجد كل نوع على خاصية مختلفة. وضع بيانات الاعتماد في المكان الخطأ هو السبب رقم 1 لأخطاء 407 Proxy Authentication Required.

// ❌ خطأ — يضبط بيانات اعتماد الخادم المستهدف، وليس البروكسي
handler.Credentials = new NetworkCredential("user", "pass");

// ✅ صحيح — يضبط بيانات الاعتماد على كائن البروكسي نفسه
handler.Proxy = new WebProxy("http://proxy:8080")
{
    Credentials = new NetworkCredential("user", "pass")
};

HttpClientHandler.Credentials تخص الوجهة النهائية. أما WebProxy.Credentials فتخص البروكسي. إذا رجّع البروكسي الخطأ 407، فبيانات الاعتماد لازم تكون على البروكسي.

فخ ثاني: HttpClientHandler.PreAuthenticate يتحكم بسلوك المصادقة المسبقة لمصادقة الخادم الهدف. وهو لا يتحكم في رأس Proxy-Authorization. لا تستخدمه كحل لمشكلة 407.

كيفية تدوير البروكسي مع HttpClient في C#

المطورون يسألون عن هذا باستمرار في المنتديات. والإجابة الأولى شوي محبطة: لا يمكنك تغيير البروكسي على كائن HttpClient وهو شغال. البروكسي يعيش على الـ handler. والـ handler يُعيَّن وقت الإنشاء. وHttpClient ما عنده خاصية Proxy قابلة للتعديل.

الحل الساذج — new HttpClient(new HttpClientHandler { Proxy = ... }) لكل طلب — يخلق مشكلة ثانية. Microsoft تحذر بوضوح من أن إنشاء العملاء والتخلص منهم لكل طلب قد يستنزف منافذ TCP المتاحة لأن المنافذ لا تتحرر فورًا بعد إغلاق الاتصال.

proxy-client-lifetime-routing.webp

لذلك، هذه ثلاثة أنماط عملية في بيئة الإنتاج تعمل فعلًا.

الخيار 1: عملاء مسمّون عبر IHttpClientFactory

إذا كانت مجموعة البروكسيات معروفة عند بدء التشغيل، فالعملاء المسمّون Named Clients هو الخيار الأقل تعقيدًا. كل عميل مسمى يحصل على إعداد handler خاص به، ويستدعيه التطبيق بالاسم وقت التشغيل.

builder.Services.AddHttpClient("proxy-us")
    .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
    {
        Proxy = new WebProxy("http://us-proxy.example.com:8080")
        {
            Credentials = new NetworkCredential("user", "pass")
        },
        UseProxy = true
    });

builder.Services.AddHttpClient("proxy-eu")
    .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
    {
        Proxy = new WebProxy("http://eu-proxy.example.com:8080")
        {
            Credentials = new NetworkCredential("user", "pass")
        },
        UseProxy = true
    });

// عند وقت الطلب:
var client = httpClientFactory.CreateClient("proxy-us");

الـ factory يدير أعمار الـ handlers ويتفادى نمط إنشاء عميل جديد لكل طلب.

الخيار 2: SocketsHttpHandler + PooledConnectionLifetime ‏(.NET 6+)

لعميل طويل العمر خلف بوابة بروكسي يتغير عنوان الخروج عند الاتصالات الجديدة، فإن PooledConnectionLifetime يفرض إعادة إنشاء الاتصالات بعد مدة معينة.

var handler = new SocketsHttpHandler
{
    Proxy = new WebProxy("http://rotating-gateway.example.com:8080")
    {
        Credentials = new NetworkCredential("user", "pass")
    },
    UseProxy = true,
    PooledConnectionLifetime = TimeSpan.FromMinutes(5)
};

using var client = new HttpClient(handler);

هذا لا يبدّل كائن Proxy سحريًا لكل طلب. لكنه يعمل بشكل ممتاز مع بوابات البروكسي التي تمنح عنوان IP مختلفًا لكل اتصال TCP جديد، أو مع مجموعات بروكسي تعتمد على DNS حيث يشير الاسم إلى نقاط نهاية مختلفة مع الوقت.

الخيار 3: DelegatingHandler مخصص لاختيار البروكسي المتقدم

عندما يعتمد اختيار البروكسي على عنوان الطلب أو الحمولة أو سياق التشغيل، يمكن لـ handler توجيه مخصص أن يفحص كل طلب ويمرّره إلى مسار المعالجة الداخلي المناسب.

public sealed class ProxyRoutingHandler : DelegatingHandler
{
    private readonly IReadOnlyDictionary<string, HttpMessageInvoker> _clients;

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        var key = SelectProxyKey(request);
        return _clients[key].SendAsync(request, cancellationToken);
    }
}

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

مقارنة بين الطرق الثلاث

النهجالتعقيدإصدار .NETأمان الخيوطالحمل الإضافي
العملاء المسمّون (IHttpClientFactory)منخفض‎.NET Core 2.1+مرتفع (تهيئة غير قابلة للتغيير)منخفض
SocketsHttpHandler + PooledConnectionLifetimeمتوسط‎.NET 6+مرتفعمنخفض
DelegatingHandler مخصصمرتفعأي إصداريعتمد على التنفيذمتوسط

بالنسبة لمعظم الفرق، العملاء المسمّون هم نقطة البداية الصحيحة. انتقل إلى PooledConnectionLifetime للبوابات المتغيرة المستقرة، واستخدم التوجيه المخصص فقط عندما يعتمد اختيار البروكسي على بيانات على مستوى الطلب.

اختيار بروتوكول البروكسي المناسب: HTTP وHTTPS وSOCKS5

ليست كل البروكسيات تتحدث اللغة نفسها، واستخدام مخطط البروتوكول الخطأ سيعطيك أخطاء مربكة.

بروكسي HTTP: يفهم طلبات HTTP. مع الوجهات HTTP العادية، يمكنه تمرير الطلب مباشرة. أما مع الوجهات HTTPS، فيرسل العميل طلب CONNECT لإنشاء نفق، ثم يتم التفاوض على TLS عبر هذا النفق مع الوجهة. هذا هو النموذج الأكثر شيوعًا.

بروكسي ينهي HTTPS: يقدم البروكسي شهادته TLS الخاصة، ثم يعيد تشفير الحركة الصادرة. هذا شائع في أنظمة الفحص المؤسسي وبعض واجهات scraping المدارة. وقد يسبب أخطاء تحقق من الشهادة إذا كان العميل لا يثق بسلسلة شهادات البروكسي.

بروكسي SOCKS5: نفق TCP على طبقة النقل يعمل مع أي حركة TCP، وليس HTTP فقط. ويُستخدم كثيرًا لدى مزودي البروكسي السكني. مدعوم محليًا في ‎.NET 6+.

مثال SOCKS5:

var handler = new SocketsHttpHandler
{
    Proxy = new WebProxy("socks5://proxy.example.com:1080")
    {
        Credentials = new NetworkCredential("proxy-user", "proxy-password")
    },
    UseProxy = true
};

using var client = new HttpClient(handler);
var ip = await client.GetStringAsync("https://api.ipify.org/");
Console.WriteLine(ip);

ملاحظة حول التحقق من شهادة SSL

عند استخدام بروكسيات تنهي HTTPS، قد ترى أخطاء RemoteCertificateNameMismatch. يمكن لـ ServerCertificateCustomValidationCallback تخصيص التحقق:

var handler = new HttpClientHandler
{
    ServerCertificateCustomValidationCallback =
        HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};

استخدم هذا فقط في التطوير المحلي أو مع بروكسي TLS-intercepting موثوق ومعتمد. إرجاع true بشكل أعمى يلغي فحصًا أمنيًا مهمًا جدًا ويعرضك لهجمات الرجل في المنتصف. في الإنتاج مع بروكسيات CONNECT أو SOCKS القياسية، أبقِ التحقق من SSL مفعّلًا.

استكشاف أخطاء البروكسي الشائعة في C# HttpClient

troubleshoot-httpclient-proxy-flowchart.webp

هذا الجدول يربط العرض الظاهر بالسبب الأرجح وأول إصلاح ينبغي تجربته. أنصحك بوضع إشارة مرجعية على هذا القسم — لأنه يغطي الأخطاء التي تظهر كثيرًا في نقاشات Stack Overflow ومنتديات المطورين.

الخطأ / العَرَضالسبب الشائعالحل
407 Proxy Authentication Requiredوُضعت بيانات الاعتماد على handler.Credentials بدلًا من handler.Proxy.Credentials؛ أو صيغة اسم المستخدم خاطئة؛ أو توجد محارف خاصة داخل كلمة المرور المضمّنة في URLاستخدم WebProxy.Credentials = new NetworkCredential(...); وتجنّب تضمين البيانات داخل URI; وتحقق من صيغة اسم المستخدم لدى المزوّد
TaskCanceledException / Timeoutنقطة نهاية البروكسي بطيئة أو غير قابلة للوصول أو مثقلة أو محجوبة بجدار ناري؛ أو مهلة 100 ثانية الافتراضية قصيرة جدًااختبر البروكسي باستخدام curl; وزد HttpClient.Timeout فقط بعد التأكد من أن النقطة تعمل؛ وأضف إعادة المحاولة وفحوصات صحة البروكسي
SocketException / استنزاف المقابسإنشاء HttpClient أو handlers والتخلص منها لكل طلباستخدم IHttpClientFactory أو عملاء singleton أو SocketsHttpHandler مع ضوابط التجميع
SSL RemoteCertificateNameMismatchاعتراض HTTPS بواسطة بروكسي مؤسسي أو مُدارثبّت/ثق CA الخاص بالبروكسي عند الحاجة؛ واستخدم التحقق المخصص فقط في بيئات تطوير مضبوطة أو سيناريوهات MITM المعتمدة
حلقة إعادة توجيه 302صفحة captive portal على بروكسي/ VPN أو حظر allowlist يعيد التوجيه مرارًااختبر الاتصال المباشر؛ وافحص رؤوس Location; وتحقق من allowlist و بوابة المصادقة
HttpRequestException / لا يوجد اتصال مع عنوان SOCKSتشغيل كود SOCKS على ‎.NET Framework أو إصدار أقدم؛ أو استخدام scheme أو port خاطئاستخدم ‎.NET 6+ للدعم المحلي لـ SOCKS؛ وتحقق من socks5://host:port; واختبر مع توثيق المزوّد
البروكسي يبدو وكأنه يتم تجاهلهUseProxy = false; أو تم تجاوز الوجهة باعتبارها محلية؛ أو متغير البيئة NO_PROXY; أو أن الـ handler مهيأ بشكل مختلف عما تتوقعاضبط UseProxy = true; وافحص HttpClient.DefaultProxy; وامسح أو تجاوز متغيرات البيئة؛ واضبط BypassProxyOnLocal = false

مسار سريع للتشخيص

  1. هل نجح الطلب؟ → نعم: قارن ناتج api.ipify.org مع عنوان IP المتوقع للبروكسي.
  2. لا، هناك رمز حالة HTTP؟ → 407: أصلح بيانات اعتماد البروكسي. 403/429: الموقع حظر البروكسي أو فرض حدًا للمعدل. حلقة 3xx: قد تكون البوابة المؤسسية/البروكسي تعيد التوجيه.
  3. لا يوجد رمز حالة، فقط استثناء؟ → Timeout: اختبر قابلية الوصول للبروكسي. استثناء Socket/الشهادة: افحص التجميع، والبروتوكول، وTLS، وإصدار .NET.

أوامر سريعة مفيدة للتحقق من البروكسي خارج .NET:

curl -x http://user:pass@proxy.example.com:8080 https://api.ipify.org/
curl --socks5 user:pass@proxy.example.com:1080 https://api.ipify.org/

إذا نجح curl لكن كود C# لم ينجح، فغالبًا الفرق يكون في طريقة المصادقة، أو مخزن ثقة TLS، أو متغيرات البيئة، أو هروب المحارف في بيانات الاعتماد. طابق عنوان البروكسي والمخطط وآلية المصادقة في curl تمامًا، ثم انقل بيانات الاعتماد إلى NetworkCredential.

متى تتجاوز إدارة البروكسي: البديل بدون كود

جزء معتبر من المطورين الذين يبحثون عن “HttpClient proxy C#” لا يحاولون تعلم نظرية البروكسي، بل يحاولون فقط إبقاء كاشف يعمل. ومن المفيد أن نكون صريحين بشأن متى يكون كود C# المخصص هو الأداة الصحيحة ومتى لا يكون كذلك.

ابنِ كاشف C# مخصصًا مع تدوير البروكسي عندما:

  • تحتاج تحكمًا كاملًا في منطق الطلبات والكوكيز والرؤوس وإعادة المحاولة والتحليل
  • يتكامل الكاشف مع قاعدة كود .NET موجودة أو خدمة داخلية
  • تتطلب متطلبات الامتثال أو الأمان أن تمتلك البنية من البداية إلى النهاية

استخدم أداة بدون كود مثل Thunderbit عندما:

  • يكون الهدف استخراج بيانات منظمة من المواقع، وليس بناء بنية HTTP
  • لا تريد صيانة مجموعات البروكسي أو التعامل مع CAPTCHA أو إصلاح استنزاف المقابس
  • يحتاج الفريق إلى البيانات في Excel أو Google Sheets أو Airtable أو Notion من دون كتابة كود تحليل

يتولى امتداد Chrome الخاص بـ Thunderbit تدوير البروكسي والتعامل مع إجراءات مكافحة البوت تلقائيًا عبر خيار الكشط السحابي. كما تتيح واجهته البرمجية للمطورين تعريف مخطط JSON والحصول على بيانات منظمة من دون إدارة HttpClient أو WebProxy أصلًا. بالنسبة للفرق التي تعمل على كشط الويب لمقارنة الأسعار أو استخراج العملاء المحتملين، فإن فرق وقت الإعداد كبير جدًا.

السيناريوC# مخصص + بروكسيThunderbit
تحكم كامل في منطق الطلباتنعملا (تحكم على مستوى API فقط)
الحاجة لإدارة البروكسينعملا (مدار تلقائيًا)
التعامل مع Anti-bot / CAPTCHAيدوي أو عبر طرف ثالثمدمج
وقت الإعدادمن ساعات إلى أيامدقائق
الأنسب لـقواعد كود .NET الحالية، والـ pipelines المخصصةاستخراج سريع للبيانات، الفرق غير التقنية، والتصدير إلى الجداول

هذا ليس دعوة لعدم استخدام HttpClient أبدًا. إذا كنت تبني خدمة .NET في بيئة إنتاج، فعليك فعلًا فهم إعداد البروكسي. لكن إذا كنت تقضي ساعات في تصحيح أخطاء 407 لمهمة جمع بيانات لمرة واحدة، فهناك خيارات أبسط — ولا عيب في استخدامها. يمكنك استكشاف أسعار Thunderbit أو زيارة قناة YouTube للاطلاع على الشروحات.

الخلاصة الأساسية

النمط الأساسي يظل نفسه: WebProxy → handler → HttpClient. وكل ما بعد ذلك يتعلق بتجنب الأخطاء التشغيلية التي تظهر في الإنتاج.

  • ضع بيانات الاعتماد على البروكسي، لا على الـ handler. المقتطفان جنبًا إلى جنب في قسم 407 هما أهم شيء لازم تتذكره.
  • لا تنشئ HttpClient جديدًا لكل طلب أو لكل بروكسي. استخدم IHttpClientFactory للعملاء المسمّين، أو SocketsHttpHandler مع PooledConnectionLifetime لبوابات التدوير، أو handler توجيه مخصص للسيناريوهات المتقدمة.
  • تحقق من إصدار .NET قبل نسخ كود SOCKS5 أو SocketsHttpHandler. جدول التوافق أعلاه يجنبك الأعطال الصامتة.
  • اختبر البروكسي خارج .NET أولًا. أمر curl سريع يزيل فئة كاملة من التشخيص.
  • لاستخراج البيانات المنظمة من دون صداع البروكسي، أدوات مثل Thunderbit تتولى طبقة النقل لتتمكن من التركيز على البيانات نفسها.

في المرة القادمة التي تصطدم فيها بـ 407 أو TaskCanceledException، ابدأ بجدول استكشاف الأخطاء أعلاه.

الأسئلة الشائعة

هل يمكنني تغيير البروكسي على مثيل HttpClient موجود بالفعل؟

لا. البروكسي مرتبط بالـ handler، والـ handler يُضبط وقت الإنشاء. HttpClient لا يوفّر خاصية Proxy قابلة للتغيير. إذا أردت بروكسيات مختلفة، فأنشئ handlers وعملاء منفصلين، وأدرهم عبر عملاء مسمّين من IHttpClientFactory أو مجموعة من العملاء المهيئين مسبقًا.

هل يستخدم HttpClient بروكسي النظام افتراضيًا؟

نعم. في ‎.NET الحديث، إذا لم تضبط handler صراحةً، فإن HttpClient يرث إعدادات البروكسي الافتراضية للنظام — بما في ذلك متغيرات البيئة مثل HTTPS_PROXY وHTTP_PROXY عبر HttpClient.DefaultProxy. ولإلغاء ذلك، اضبط UseProxy = false صراحةً على الـ handler.

كيف أستخدم بروكسي SOCKS5 مع HttpClient في C#؟

استخدم new WebProxy("socks5://host:port") مع SocketsHttpHandler. الدعم المحلي لبروكسي SOCKS يتطلب ‎.NET 6 أو أحدث. أما في ‎.NET Framework 4.x، فـ SOCKS5 غير مدعوم محليًا — وستحتاج إلى مكتبة طرف ثالث.

لماذا أستمر في الحصول على 407 Proxy Authentication Required؟

على الأغلب لأنك تضع بيانات الاعتماد على handler.Credentials (الموجّهة إلى الخادم النهائي) بدلًا من handler.Proxy.Credentials (الموجّهة إلى البروكسي). راجع قسم “بيانات اعتماد البروكسي مقابل بيانات اعتماد الخادم” أعلاه لمعرفة النمط الصحيح.

هل من الآمن تعطيل التحقق من شهادة SSL عند استخدام بروكسي؟

فقط في التطوير المحلي أو عندما تثق تمامًا في مزوّد البروكسي (مثل API كشط مُدارة تعمل بوضع HTTPS proxy). في الإنتاج مع بروكسيات CONNECT أو SOCKS القياسية، أبقِ التحقق من SSL مفعّلًا لمنع هجمات الرجل في المنتصف.

جرّب Thunderbit لكشط الويب بسهولة Get Started Free

اعرف المزيد

Fawad Khan
Fawad Khan
فاواد يكتب ليكسب رزقه، وبصراحة هو يحب ذلك نوعًا ما. أمضى سنوات وهو يكتشف ما الذي يجعل سطرًا من النص الإعلاني يعلق في الذهن، وما الذي يجعل القراء يتجاوزونه بالتمرير. اسأله عن التسويق، وسيحدثك لساعات. واسأله عن الكاربونارا، وسيطيل الحديث أكثر.
Topics
أدوات كشط الويبAI Web Scraper
جدول المحتويات
Thunderbit · وكيل بيانات الويب بالذكاء الاصطناعي

Extract data from any page in 1 click

موثوق به من قبل أكثر من 250,000 مستخدم
الخطة المجانية متاحة
استخرج البيانات باستخدام الذكاء الاصطناعي
انقل البيانات بسهولة إلى Google Sheets أو Airtable أو Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week