مقدمه
در این مقاله یاد میگیرید چگونه با استفاده از Selenium Wire قابلیتهای شبکهای مرورگر Selenium را در پایتون گسترش دهید تا کنترل، نظارت و اصلاح درخواستها و پاسخها را در جریان اسکریپینگ داشته باشید. این راهنما برای توسعهدهندگان پایتون در سطح متوسط طراحی شده و شامل نصب، نمونههای عملی (پراکسیهای احراز هویت، اینترسپتورها، مسدودسازی و پاسخهای ساختگی)، و نکات امنیتی و عملکردی است.
پس از خواندن این مطلب باید بتوانید: نصب و راهاندازی selenium-wire را انجام دهید، درخواستها و پاسخها را مشاهده و تغییر دهید، از پراکسیهای احراز هویت استفاده کنید، و از تکنیکهایی برای کاهش شناسایی و بهبود کارایی بهرهمند شوید.
چیست و چرا استفاده کنیم
Selenium Wire یک افزونه برای Selenium در پایتون است که یک پروکسی محلی/سرور پسزمینه راهاندازی میکند و تمام ترافیک HTTP/HTTPS مرورگر تحت کنترل Selenium را رهگیری میکند. مزیت اصلی این است که بدون تغییر رفتار معمول Selenium میتوانید به درخواستها و پاسخها دسترسی پیدا کنید، آنها را تغییر دهید یا حتی پاسخهای ساختگی بسازید.
موارد کاربردی معمول:
- استفاده از پراکسیهای با احراز هویت
- ثبت دقیق درخواستها برای دیباگ و مانیتورینگ
- تزریق هدرها یا پارامترها برای عبور از محدودیتها
- مسدودسازی منابع غیرضروری برای بهبود سرعت
- آزمایش رفتار اپلیکیشن با پاسخهای ساختگی
نصب و راهاندازی اولیه
ابتدا بسته را با pip نصب کنید:
pip install selenium-wire
سپس به جای وارد کردن selenium.webdriver، از seleniumwire.webdriver وارد میکنیم تا به قابلیتهای اضافی دسترسی داشته باشیم:
from seleniumwire import webdriver
# نمونه ساده: ساخت مرورگر کروم و بازدید یک صفحه
driver = webdriver.Chrome()
driver.get('https://www.example.com')
# لیست درخواستهای ثبتشده
requests = driver.requests
توضیح ورودی/خروجی: این کد هیچ ورودی خارجی نیاز ندارد به جز نصب webdriver و کروم/درایور مناسب؛ خروجی دسترسی به driver.requests است که لیستی از اشیاء درخواست را برمیگرداند.
ساختار اشیاء Request و Response
بعد از اجرا، selenium-wire هر درخواست و پاسخ را به صورت شیء فراهم میکند. مهمترین ویژگیهای قابل استفاده برای اشیاء درخواست:
- body: محتوای درخواست به صورت بایتها (b'')
- headers: دیکشنری-مانند هدرها
- method: متد HTTP مثل GET یا POST
- url: URL کامل درخواست
- params: پارامترهای کوئری به صورت دیکشنری
- response: شیء پاسخ مرتبط (ممکن است None باشد)
ویژگیهای مهم پاسخ:
- status_code: کد وضعیت HTTP
- headers: هدرهای پاسخ
- body: بدنه پاسخ به صورت بایت
نکته عملی: دسترسی به این اشیاء برای دیباگ کردن APIهایی که در پشت SPAها یا درخواستهای AJAX قرار دارند بسیار مفید است.
اینترسپتورها: intercept کردن درخواستها و پاسخها
قلب قابلیتهای Selenium Wire، اینترسپتورها هستند. شما میتوانید قبل از باز شدن درخواست یا پس از دریافت پاسخ، توابعی تعیین کنید:
- اینترسپتور درخواست: تابعی که یک آرگومان request میگیرد.
- اینترسپتور پاسخ: تابعی که دو آرگومان request و response میگیرد.
def my_request_interceptor(request):
# نمونه: افزودن هدر
request.headers['X-My-Header'] = 'value'
def my_response_interceptor(request, response):
# نمونه: مشاهده وضعیت پاسخ
print(request.url, response.status_code)
# تنظیم روی درایور
driver.request_interceptor = my_request_interceptor
driver.response_interceptor = my_response_interceptor
# پس از اتمام کار، برای حذف
# del driver.request_interceptor
# del driver.response_interceptor
توضیح: تابع اینترسپتور درخواست ورودی request را دریافت میکند و میتواند هدرها، پارامترها، یا حتی رفتار درخواست را تغییر دهد. اینترسپتور پاسخ برای بررسی یا تغییر محتوای پاسخ کاربرد دارد.
تغییر هدرها و پارامترهای درخواست
مثال: اضافه کردن یا جایگزینی هدر در همه درخواستها.
def interceptor(request):
# افزودن هدر جدید
request.headers['New-Header'] = 'Some Value'
# جایگزینی هدر موجود: ابتدا حذف سپس اضافه
if 'Referer' in request.headers:
del request.headers['Referer']
request.headers['Referer'] = 'https://spoofed.example'
driver.request_interceptor = interceptor
برای پارامترهای کوئری توجه کنید که ابتدا باید request.params را بخوانید، تغییر دهید و دوباره مقداردهی کنید:
def param_interceptor(request):
params = request.params
params['foo'] = 'bar'
request.params = params # بازنویسی پارامترها
driver.request_interceptor = param_interceptor
نکته: پارامترها به صورت دیکشنری معمولی ذخیره میشوند؛ بنابراین پارامترهای تکراری با یکدیگر بازنویسی خواهند شد مگر اینکه خودتان لیست مقدارها را مدیریت کنید.
پراکسیهای احراز هویت (Authenticated Proxies)
شیوهٔ معمول افزودن پراکسی به گزینههای مرورگر برای پراکسیهای بدون احراز هویت خوب کار میکند، اما اگر پراکسی نیاز به username و password داشته باشد، شیوهٔ پیشفرض کروم مشکلساز است. Selenium Wire این مساله را با تنظیم seleniumwire_options حل میکند:
from seleniumwire import webdriver
proxy_options = {
'proxy': {
'http': 'http://USERNAME:PASSWORD@proxy-server:8080',
'https': 'http://USERNAME:PASSWORD@proxy-server:8080',
'no_proxy': 'localhost,127.0.0.1'
}
}
driver = webdriver.Chrome(seleniumwire_options=proxy_options)
driver.get('https://httpbin.org/ip')
توضیح: seleniumwire_options یک دیکشنری است که تنظیمات خاص پروکسی را به سرور رهگیر میدهد. ورودیها باید شامل رشتهٔ پراکسی با اطلاعات کاربری باشند.
نکات امنیتی: از نگهداری طولانیمدت اسمکاربری/کلمهعبور در کد خودداری کنید و از متغیرهای محیطی یا مدیر اسرار (secret manager) استفاده کنید.
مسدودسازی منابع برای افزایش سرعت
برای کاهش پهنایباند یا افزایش سرعت بارگذاری میتوانید درخواستهای مربوط به تصاویر، فونت یا اسکریپتهای غیرضروری را مسدود کنید:
def block_images(request):
if request.path.endswith(('.png', '.jpg', '.gif')):
request.abort() # پیشفرض کد خطا 403
driver.request_interceptor = block_images
توضیح: request.abort() باعث میشود مرورگر پاسخ فوری (مثلاً 403) دریافت کند و درخواست به سرور خارجی ارسال نشود.
هشدار: برخی سایتها بارگیری منابع را برای عملکرد صفحه لازم دارند؛ پیش از مسدودسازی عمومی، تست کنید که UI یا API موردنظر آسیب نبیند.
پاسخهای ساختگی (Mocking)
گاهی لازم است برای تست یا جلوگیری از تماس با سرویس خارجی، پاسخ ساختگی به مرورگر بازگردانید:
def mock_home(request):
if request.url == 'https://www.example.com/':
request.create_response(
status_code=200,
headers={'Content-Type': 'text/html'},
body='Mocked!
'
)
driver.request_interceptor = mock_home
توضیح: create_response() از ارسال درخواست به سرور جلوگیری میکند و مستقیماً پاسخ دادهشده را به مرورگر بازمیگرداند.
احراز هویت پایه (Basic Authentication)
برای جلوگیری از نمایش پنجرهٔ نامکاربری/کلمهعبور میتوانید هدر Authorization را در اینترسپتور قرار دهید:
import base64
credentials = base64.b64encode('my_user:my_pass'.encode()).decode()
def basic_auth_interceptor(request):
if request.host == 'www.example.com':
request.headers['Authorization'] = f'Basic {credentials}'
driver.request_interceptor = basic_auth_interceptor
نکته امنیتی: رمزنگاری ساده Base64 قابل بازیابی است؛ برای انتقال امن از HTTPS استفاده کنید و از ذخیرهٔ مستقیم رمز در کد خودداری نمایید.
عبور از تشخیص ربات (Undetected Chromedriver)
درایور استاندارد کروم ممکن است سرنخهایی به آنتیباتها بدهد. نسخههای بهینهشده مانند undetected-chromedriver تلاش میکنند این اثرات را کم کنند. Selenium Wire میتواند با نسخهٔ بهینهشده یکپارچه شود:
import seleniumwire.undetected_chromedriver as uc
chrome_options = uc.ChromeOptions()
# میتوانید هرگز گزینههای کروم را اضافه کنید
driver = uc.Chrome(options=chrome_options, seleniumwire_options={})
driver.get('https://sensitive-site.example')
نکته عملی: استفاده از این ابزارها به صورت تضمینی از بلاک شدن جلوگیری نمیکند؛ ترکیب روشها مثل پراکسی، تاخیرهای تصادفی و مدیریت کوکی/سشن معمولاً لازم است.
عملکرد، پایداری و نکات عملی
- برای تولید لاگهای طولانی، فضای ذخیرهٔ درخواستها را مدیریت کنید تا حافظه پر نشود.
- در موازاتسازی (concurrency) با چند درایور، هر درایور پروکسی/سرور خود را دارد؛ منابع سیستمی را مانیتور کنید.
- در زمان اجرا از del driver.request_interceptor برای حذف اینترسپتورها استفاده کنید تا از اثرگذاری ناخواسته جلوگیری شود.
- همیشه قبل از اجرای عمده اسکریپها قوانین سایت و ملاحظات اخلاقی/قانونی را بررسی کنید.
جمعبندی
Selenium Wire ابزار قدرتمندی برای کسانی است که میخواهند فراتر از تعامل سادهٔ DOM با وبسایتها کار کنند؛ با آن میتوانید ترافیک را مشاهده، تغییر، مسدود یا ساختگی کنید و حتی پراکسیهای احراز هویت را مدیریت نمایید. ترکیب این امکانات با مدیریت امنیت (ذخیره امن credentials)، مدیریت منابع و تکنیکهای عبور از شناسایی میتواند کارایی و موفقیت اسکریپهای شما را بهطور چشمگیری افزایش دهد.
توصیه نهایی: ابتدا نمونههای کوچک بسازید و رفتار سایت را بررسی کنید، سپس قابلیتهایی مثل مسدودسازی یا پاسخهای ساختگی را وارد جریان اصلی کنید تا خطا و اثرات جانبی را به حداقل برسانید.
آسان اسکریپ را در گوگل بهعنوان منبع ترجیحی انتخاب کن
مقالههای جدید ما زودتر و پررنگتر در نتایج گوگل و Discover برایت نمایش داده میشود. افزودن از تنظیمات گوگل





