نحوه رفع مشکلات کوکیها از طریق پروکسی
کوکیها یکی از رایجترین منابع خطا هنگام کار با پروکسی هستند. جلسات قطع میشوند، احراز هویت دچار مشکل میشود، دادهها از دست میروند. در این مقاله بررسی میکنیم که چرا این اتفاق میافتد و نحوه تنظیم صحیح مدیریت کوکیها برای کار پایدار.
چرا کوکیها هنگام استفاده از پروکسی از دست میروند
هنگامی که درخواستی را از طریق پروکسی ارسال میکنید، یک گره میانی بین کلاینت شما و سرور هدف قرار میگیرد. این مسائل متعددی ایجاد میکند:
- آدرسهای IP متفاوت برای یک جلسه. سرور ممکن است متوجه شود که درخواستها از آدرسهای مختلف میآیند و کوکیها را بهعنوان مشکوک رد کند.
- از دست رفتن سرصحافههای Set-Cookie. تنظیم نادرست پروکسی ممکن است سرصحافههای Set-Cookie را به کلاینت منتقل نکند.
- عدم تطابق دامنه و مسیر. اگر پروکسی سرصحافه Host را بازنویسی کند، کوکیها ممکن است به دلیل عدم تطابق دامنه ذخیره نشوند.
- عدم وجود ذخیرهسازی وضعیت. اگر هر درخواست را بدون ذخیره کوکیها جداگانه ارسال کنید، جلسه از دست خواهد رفت.
کوکی جار چیست و نحوه استفاده از آن
کوکی جار یک ذخیرهگاه کوکی است که بهطور خودکار مدیریت ارسال و دریافت آنها را انجام میدهد. بهجای افزودن دستی سرصحافه Cookie به هر درخواست، اجازه میدهید کتابخانه این کار را بهطور خودکار انجام دهد.
اکثر کلاینتهای HTTP دارای پشتیبانی داخلی برای کوکی جار هستند:
import requests
from requests.cookies import RequestsCookieJar
# جار برای ذخیرهسازی کوکیها ایجاد میکنیم
jar = RequestsCookieJar()
# درخواست اول — سرور Set-Cookie ارسال میکند
response1 = requests.get(
'https://example.com/login',
cookies=jar,
proxies={'https': 'http://proxy.example.com:8080'}
)
# کوکیها بهطور خودکار در جار ذخیره شدند
print(jar)
# درخواست دوم — کوکیها بهطور خودکار ارسال میشوند
response2 = requests.get(
'https://example.com/dashboard',
cookies=jar,
proxies={'https': 'http://proxy.example.com:8080'}
)
بدون جار باید بهصورت دستی Set-Cookie را تجزیه کنید و آنها را به درخواست بعدی اضافه کنید — این ناپایدار و دشوار است.
ذخیره کوکیها بین درخواستها
اگر اسکریپت شما مدت طولانی کار میکند یا نیاز دارید جلسه را پس از بارگذاری مجدد بازیابی کنید، کوکیها را در یک فایل ذخیره کنید:
import requests
from http.cookiejar import LWPCookieJar
# جار با ذخیرهسازی در فایل ایجاد میکنیم
jar = LWPCookieJar('cookies.txt')
# کوکیهای قدیمی را بارگذاری میکنیم اگر وجود داشته باشند
try:
jar.load(ignore_discard=True, ignore_expires=True)
except FileNotFoundError:
pass
# جار را در درخواستها استفاده میکنیم
response = requests.get(
'https://example.com/login',
cookies=jar,
proxies={'https': 'http://proxy.example.com:8080'}
)
# کوکیهای بهروز شده را ذخیره میکنیم
jar.save(ignore_discard=True, ignore_expires=True)
پرچمهای ignore_discard=True و ignore_expires=True اجازه میدهند حتی کوکیهای موقت را ذخیره کنید.
مشکلات مربوط به اتصال دامنه کوکیها
کوکیها دارای ویژگی Domain هستند که تعیین میکند برای کدام دامنهها ارسال خواهند شد. مشکلات زمانی بروز میکند که:
- پروکسی Host را بازنویسی میکند. اگر پروکسی سرصحافه Host را تغییر دهد، کوکی جار ممکن است کوکی را بهعنوان متعلق به دامنه دیگری رد کند.
- زیردامنهها مطابقت ندارند. کوکی برای
example.comممکن است بهapi.example.comارسال نشود. - مسیر مطابقت ندارد. کوکی برای
/apiبه/adminارسال نخواهد شد.
ویژگیهای کوکی را بهاینگونه بررسی کنید:
import requests
response = requests.get(
'https://example.com',
proxies={'https': 'http://proxy.example.com:8080'}
)
# تمام کوکیها را نمایش میدهیم
for cookie in response.cookies:
print(f"Name: {cookie.name}")
print(f"Value: {cookie.value}")
print(f"Domain: {cookie.domain}")
print(f"Path: {cookie.path}")
print(f"Secure: {cookie.secure}")
print(f"HttpOnly: {cookie.has_nonstandard_attr('HttpOnly')}")
print("---")
اگر Domain خیلی محدود است، سعی کنید کوکیها را بهصورت صریح مشخص کنید بهجای مدیریت خودکار:
headers = {
'Cookie': 'session_id=abc123; user_token=xyz789'
}
response = requests.get(
'https://example.com/api',
headers=headers,
proxies={'https': 'http://proxy.example.com:8080'}
)
پرچمهای Secure و HttpOnly
پرچم Secure بهمعنای این است که کوکی تنها از طریق HTTPS ارسال میشود. اگر از پروکسی HTTP برای دسترسی به منبع HTTPS استفاده میکنید، مطمئن شوید که اتصال به پروکسی محافظتشده است یا پروکسی بهدرستی HTTPS را پروکسی میکند.
پرچم HttpOnly دسترسی به کوکی از JavaScript را ممنوع میکند. این بر ارسال کوکی در درخواستها تأثیر نمیگذارد، اما مهم است که بدانید نمیتوانید چنین کوکیهایی را از مرورگر بخوانید.
هنگام کار با پروکسیهای مسکونی مطمئن شوید که:
- پروکسی از HTTPS پشتیبانی میکند (روش CONNECT)
- گواهیها معتبر هستند (از
verify=Falseدر تولید استفاده نکنید) - سرصحافهها توسط پروکسی بازنویسی نمیشوند
نمونههای عملی با کد
نمونه 1: ورود با ذخیرهسازی جلسه
import requests
from requests.cookies import RequestsCookieJar
jar = RequestsCookieJar()
proxy = 'http://proxy.example.com:8080'
# ورود
login_response = requests.post(
'https://example.com/login',
data={'username': 'user', 'password': 'pass'},
cookies=jar,
proxies={'https': proxy}
)
if login_response.status_code == 200:
print("ورود موفق")
# جلسه ذخیرهشده را استفاده میکنیم
dashboard = requests.get(
'https://example.com/dashboard',
cookies=jar,
proxies={'https': proxy}
)
print(dashboard.text)
نمونه 2: پردازش درخواستهای متعدد
import requests
from http.cookiejar import LWPCookieJar
import time
jar = LWPCookieJar('session.txt')
try:
jar.load(ignore_discard=True)
except:
pass
proxy = 'http://proxy.example.com:8080'
urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3'
]
for url in urls:
response = requests.get(
url,
cookies=jar,
proxies={'https': proxy},
timeout=10
)
print(f"{url}: {response.status_code}")
jar.save(ignore_discard=True)
time.sleep(1) # سرور را بیشبار نکنید
نمونه 3: انتقال صریح کوکیها در صورت مشکل
import requests
proxy = 'http://proxy.example.com:8080'
# اگر مدیریت خودکار کار نکند
cookies_dict = {
'session_id': 'abc123def456',
'user_pref': 'dark_mode'
}
headers = {
'User-Agent': 'Mozilla/5.0...',
'Cookie': '; '.join([f"{k}={v}" for k, v in cookies_dict.items()])
}
response = requests.get(
'https://example.com/api/data',
headers=headers,
proxies={'https': proxy}
)
print(response.json())
رفع عیب مشکلات کوکیها
اگر کوکیها کار نکنند، از این ابزارها استفاده کنید:
| ابزار | هدف |
|---|---|
requests.Session |
بهطور خودکار کوکیها را برای تمام درخواستها در جلسه مدیریت میکند |
logging |
DEBUG را برای requests فعال کنید تا تمام سرصحافهها را ببینید |
Fiddler / Charles |
ترافیک را قطع کنید و سرصحافههای Set-Cookie و Cookie را ببینید |
curl -v |
همان چیز را از طریق پروکسی از خط فرمان آزمایش کنید |
برای رفع عیب، ثبتکردن را فعال کنید:
import logging
import requests
logging.basicConfig(level=logging.DEBUG)
# اکنون تمام درخواستها سرصحافهها و کوکیها را نمایش میدهند
response = requests.get(
'https://example.com',
proxies={'https': 'http://proxy.example.com:8080'}
)
بررسی کنید که پروکسی کوکیها را مسدود نمیکند:
curl -v -x http://proxy.example.com:8080 https://example.com
# سرصحافهها را ببینید:
# Set-Cookie: ... (باید وجود داشته باشند)
# Cookie: ... (باید در درخواست بعدی ارسال شوند)
نکته: اگر از پروکسیهای مسکونی استفاده میکنید، بهیاد داشته باشید که آنها ممکن است IP را بین درخواستها تغییر دهند. مطمئن شوید که منطق مدیریت کوکیهای شما این را در نظر میگیرد — برخی سرورها درخواستها را از IPهای مختلف در یک جلسه رد میکنند.
خلاصه
مشکلات کوکی هنگام کار از طریق پروکسی با تنظیم صحیح حل میشوند:
- از کوکی جار برای مدیریت خودکار کوکیها استفاده کنید
- کوکیها را بین درخواستها در فایل ذخیره کنید
- اتصال دامنه و ویژگیهای Path را بررسی کنید
- از پشتیبانی HTTPS پروکسی اطمینان حاصل کنید
- برای شناسایی مشکلات از رفع عیب استفاده کنید
برای وظایف خودکارسازی و تجزیهگری که نیاز به کار قابلاعتماد با جلسات از طریق پروکسی دارند، پروکسیهای مسکونی با پشتیبانی HTTPS و مدیریت کوکیها مناسب هستند. از کوکی جار ساده شروع کنید و تنها در صورت نیاز به طرحهای پیچیدهتر بروید.