wget ابزاری خط فرمانی است که در سیستمهای Linux و macOS اغلب از پیش نصب شده و برای دانلود فایل و دریافت صفحههای وب به کار میرود. در سرورها برای دانلود فایل از درون اسکریپت، آینهسازی یک سایت یا یک آزمون ساده دسترسی بسیار استفاده میشود. در این نوشته سه راه اجرای wget از طریق پروکسی، احراز هویت، جزئیات HTTPS، نکتههای دانلود انبوه و خطاهای رایج را با دستورهای نمونه شرح میدهیم.
همه گزینههایی که در اینجا آمده در راهنمای GNU Wget مستند شدهاند.
پیش از شروع: wget نصب است؟
در ترمینال نسخه را بررسی کنید:
wget --versionاگر دستور پیدا نشد، در Debian و Ubuntu از sudo apt install wget و در macOS با Homebrew از brew install wget استفاده کنید. در Windows ابزار wget درونساخت نیست؛ برای همین کارها میتوان curl.exe را که از Windows 10 به بعد همراه سیستم است ترجیح داد. نوشتن wget در PowerShell هم wget واقعی نیست، بلکه نام مستعار دستور Invoke-WebRequest است و گزینههای این نوشته را نمیپذیرد.
در آزمایشها استفاده از یک نشانی آزمون که IP شما را برمیگرداند کار را آسان میکند. اگر پروکسی کار کند، این نشانی نه IP شما بلکه IP پروکسی را نشان میدهد:
wget -qO- https://httpbin.org/ipدر اینجا -q خروجی را بیصدا میکند و -O- محتوای دانلودشده را بهجای نوشتن در فایل روی صفحه چاپ میکند. پیش از تعریف پروکسی یک بار اجرا کنید و IP خودتان را یادداشت کنید؛ در آزمایشهای بعدی تفاوت را بیدرنگ میبینید.
قالب نشانی پروکسی
در هر سه روش پروکسی به یک شکل نوشته میشود:
http://user:pass@server:port- طرح
http://پروتکل اتصالی است که با پروکسی برقرار میشود. هنگام رفتن به سایتهای HTTPS هم همین طرح به کار میرود؛ دلیلش را در ادامه توضیح میدهیم. - بخش
user:pass@اختیاری است. اگر از پنل پروکسی IP سرور خود را مجاز کردهاید، میتوانید این بخش را کاملاً کنار بگذارید. - اطلاعات
server:portبسته به بسته شما تغییر میکند؛ مقدارهای درست را در پنل مشتری خود مییابید.
روش 1: با متغیرهای محیطی
wget متغیرهای محیطی استاندارد پروکسی در سیستم را میخواند: http_proxy، https_proxy، ftp_proxy و no_proxy. سریعترین روش همین است و بسیاری از ابزارهای دیگری که در همان ترمینال اجرا میشوند نیز از این متغیرها استفاده میکنند.
export http_proxy="http://user:pass@pr.proxynet.io:8000"
export https_proxy="http://user:pass@pr.proxynet.io:8000"
wget -qO- https://httpbin.org/ipسه نکته را باید در نظر گرفت:
- مقدار
https_proxyهم باhttp://شروع میشود. این متغیر پروکسیای را که هنگام رفتن به سایتهای HTTPS به کار میرود مشخص میکند؛ اتصالی که با خود پروکسی برقرار میشود HTTP است و ترافیک HTTPS درون این اتصال تونل میشود. - متغیرها فقط در همان نشست ترمینال معتبرند. اگر میخواهید ماندگار باشند، آنها را به فایل
~/.bashrcیا~/.zshrcبیفزایید. - نگارش با حروف کوچک را ترجیح دهید. wget متغیرهای با حروف کوچک را میخواند؛ در برخی سیستمها
HTTP_PROXYبا حروف بزرگ هم تعریف شده است و اگر دو تعریف با هم ناسازگار باشند گیجکننده میشود. تنظیم هر دو روی یک مقدار مطمئنترین کار است.
اگر میخواهید برخی نشانیها به پروکسی نروند از no_proxy استفاده کنید:
export no_proxy="localhost,127.0.0.1,.company.local"این متغیر جلوی گذر سرویسهای شبکه داخلی یا سرورهای توسعه محلی از پروکسی را میگیرد. نام دامنهای که با نقطه شروع شود، همه زیردامنههای آن دامنه را در بر میگیرد.
روش 2: در خط فرمان، یکباره
برای عبور دادن فقط یک دستور از پروکسی بدون تغییر متغیرهای محیطی، میتوانید با گزینه -e (--execute) تنظیمات wget را مستقیم به دستور بدهید:
wget -e use_proxy=yes \
-e https_proxy=http://pr.proxynet.io:8000 \
--proxy-user=user \
--proxy-password=pass \
https://httpbin.org/ip -O -این روش بهویژه در اسکریپتها کاربردی است: تنظیم پروکسی بر دستورهای دیگر اثر نمیگذارد و در هر فراخوانی میتوانید پروکسی متفاوتی بدهید. مثلاً اگر میخواهید در یک حلقه هر دانلود را از نقطه خروجی متفاوتی انجام دهید، مقدار -e https_proxy= را از متغیر حلقه میگیرید.
هر خطی که با -e داده میشود تنظیمی است که میتوان در فایل .wgetrc نوشت. یعنی هر کلیدی که در روش بعدی میبینید اینجا هم معتبر است.
روش 3: با فایل wgetrc، بهصورت ماندگار
اگر در یک دستگاه همیشه wget را با پروکسی به کار میبرید، میتوانید تنظیمات را در فایل ~/.wgetrc در پوشه کاربری خود بنویسید:
use_proxy = on
http_proxy = http://pr.proxynet.io:8000
https_proxy = http://pr.proxynet.io:8000
proxy_user = user
proxy_password = passچون فایل رمز عبور دارد، مجوزهایش را طوری محدود کنید که فقط خودتان بتوانید آن را بخوانید:
chmod 600 ~/.wgetrcاگر تنظیمی سراسری در سیستم لازم است، همین خطها را میتوان در فایل /etc/wgetrc نوشت؛ فایل پوشه کاربری مقدارهای فایل سیستمی را بازنویسی میکند.
اگر این فایل تعریف شده و میخواهید پروکسی را موقتاً غیرفعال کنید، برای یک دستور گزینه --no-proxy را بیفزایید:
wget --no-proxy https://httpbin.org/ip -O -کدام روش را انتخاب کنیم؟
| وضعیت | روش پیشنهادی |
|---|---|
| یک آزمون سریع در ترمینال | متغیر محیطی |
| در اسکریپت، پروکسی متفاوت در هر فراخوانی | خط فرمان با -e |
| استفاده همیشگی از پروکسی در سرور | فایل .wgetrc |
| بیرون نگه داشتن برخی نشانیها از پروکسی | no_proxy |
| دانلود زمانبندیشده با cron | فایل .wgetrc (cron متغیرهای محیطی را منتقل نمیکند) |
| درون کانتینر Docker | متغیر محیطی (با ENV) |
اگر هر سه روش همزمان تعریف شده باشند، ترتیب اولویت چنین است: گزینههای خط فرمان متغیرهای محیطی را و متغیرهای محیطی فایل .wgetrc را بازنویسی میکنند.
پروکسی در سایتهای HTTPS چگونه کار میکند؟
هنگام رفتن به یک نشانی HTTPS از طریق پروکسی، wget نخست درخواست CONNECT target:443 را به پروکسی میفرستد. پروکسی با مقصد یک اتصال TCP باز میکند و از آن پس فقط بایتهای رمزگذاریشده را جابهجا میکند. یعنی پروکسی محتوای سایت را نمیبیند؛ فقط میداند به کدام نام دامنه وصل شدهاید.
نتیجه عملی این است: حتی اگر نشانی پروکسی با http:// شروع شود، میتوانید با اطمینان به سایتهای HTTPS بروید. تأیید گواهی میان دستگاه شما و سایت مقصد انجام میشود و پروکسی در آن دخالتی ندارد. این رفتار پروکسی و تفاوتش با SOCKS را در نوشته تفاوت پروکسی SOCKS و HTTP مقایسه کردهایم.
همراه با گزینههای پرکاربرد
تنظیم پروکسی بهتنها بهندرت کافی است؛ در کارهای واقعی چند گزینه دیگر هم لازم است. نمونه زیر یک فایل را از طریق پروکسی با تنظیمات تلاش دوباره و مهلت دانلود میکند:
wget --timeout=30 --tries=3 --waitretry=5 \
--user-agent="Mozilla/5.0 (X11; Linux x86_64)" \
-O report.pdf https://example.com/report.pdf- گزینه
--timeoutزمان انتظار هر عملیات شبکه را محدود میکند. - گزینه
--triesتعیین میکند دانلود ناموفق چند بار دوباره آزموده شود؛--waitretryمیان تلاشها انتظار میگذارد. - گزینه
--user-agentشناسه مرورگر را تغییر میدهد. شناسه پیشفرض wget در برخی سایتها مستقیم مسدود میشود؛ به کار بردن مقداری معرف هم شفافتر است و هم دردسر کمتری دارد. - گزینه
-Oنام فایل خروجی را تعیین میکند؛ اگر-cرا بیفزایید، دانلود نیمهکاره از همان جایی که مانده ادامه مییابد.
اگر هنگام دریافت صفحه کوکی لازم است، گزینههای --load-cookies و --save-cookies نشست را در فایل نگه میدارند؛ ادامه دادن نشستی که وارد حساب شده همراه با پروکسی به این شکل ممکن است.
آیا wget از پروکسی SOCKS پشتیبانی میکند؟
wget از پروژه GNU پشتیبانی درونساخت از SOCKS ندارد؛ همه روشهای بالا برای پروکسی HTTP و HTTPS هستند. اگر باید از SOCKS5 استفاده کنید، دو گزینه دارید:
- استفاده از cURL. cURL طرحهای
socks5://وsocks5h://را مستقیم پشتیبانی میکند و تقریباً هر کاری که wget انجام میدهد را انجام میدهد. جزئیات در نوشته استفاده از پروکسی با cURL آمده است. - استفاده از ابزار مسیردهی. در Linux ابزارهایی مانند
proxychainsمیتوانند اتصالهای برنامههایی را که از SOCKS پشتیبانی نمیکنند به پروکسی SOCKS هدایت کنند. در Windows همین کار را Proxifier انجام میدهد.
برای بستههایی که مستقیم با wget کار میکنند صفحه پروکسی HTTPS را ببینید.
خطاهای رایج و راهحلها
خطای «407 Proxy Authentication Required»
اطلاعات ورود پروکسی ناقص یا نادرست است. نام کاربری و رمز عبور را بررسی کنید. اگر رمز عبور نویسههای ویژهای مانند @، : یا # دارد، آنها را درون نشانی با کدگذاری درصدی بنویسید (برای @ مقدار %40) یا از گزینههای --proxy-user و --proxy-password استفاده کنید؛ این گزینهها به کدگذاری نیاز ندارند.
دستور اصلاً از پروکسی استفاده نمیکند
- مطمئن شوید متغیر را با
exportتعریف کردهاید؛ نوشتن فقطhttp_proxy=...آن را به فرایندهای فرزند منتقل نمیکند. - اگر به یک نشانی HTTPS میروید، باید نه
http_proxyبلکهhttps_proxyتعریف شده باشد. - بررسی کنید در
.wgetrcخطuse_proxy = offوجود نداشته باشد. - اگر
sudo wgetاجرا میکنید،sudoممکن است بهطور پیشفرض متغیرهای محیطی شما را منتقل نکند؛ باsudo -Eمنتقل کنید یا تنظیم را در فایل/etc/wgetrcبنویسید. - ممکن است نشانی مقصد با دامنهای در فهرست
no_proxyمطابقت داشته باشد.
خطای «Unable to establish SSL connection»
نخست بررسی کنید آیا نشانی مقصد بدون پروکسی باز میشود. اگر مشکل از گواهی است، گزینه --no-check-certificate تأیید را نادیده میگیرد؛ اما این گزینه امنیت اتصال را ضعیف میکند و فقط باید برای آزمون به کار رود. به یاد داشته باشید که پروکسی در تأیید گواهی دخالتی ندارد: این خطا معمولاً از قدیمی بودن مخزن گواهی ریشه در سیستم یا از پیکربندی سایت مقصد ناشی میشود.
اتصال به پایان مهلت میرسد
نشانی و درگاه پروکسی را دوباره بررسی کنید. مطمئن شوید دیواره آتش اجازه ترافیک به درگاه پروکسی را میدهد. در دانلودهای طولانی، تعیین صریح مهلت و تعداد تلاش دوباره از گیر کردن اسکریپتها جلوگیری میکند:
wget --timeout=30 --tries=3 https://httpbin.org/ip -O -خطای «ERROR 403: Forbidden»
سایت مقصد درخواست را رد میکند. ممکن است علت پروکسی نباشد؛ مقدار پیشفرض User-Agent در wget در برخی سایتها مستقیم مسدود میشود. با --user-agent مقداری معرف بدهید. اگر مشکل ادامه یافت، ممکن است سایت مقصد بسته به نوع IP پروکسی رفتار کند؛ اینکه چرا نشانیهای مرکز داده بیشتر رد میشوند را در نوشته تفاوت پروکسی مسکونی و دیتاسنتر توضیح دادهایم.
نکتههای دانلود انبوه
گزینه -r (دانلود بازگشتی) در wget میتواند کل یک سایت را با یک دستور دریافت کند. این توان ممکن است بار جدی بر سرور مقصد بگذارد. در دانلودهای انبوه این گزینهها هم به سود شما و هم به سود مقصد است:
wget -r -l 2 --wait=2 --random-wait --limit-rate=500k \
--no-parent -A pdf https://example.com/documents/- گزینه
-l 2عمق را به دو سطح محدود میکند؛ عمق نامحدود کل سایت را دانلود میکند. - گزینه
--wait=2میان درخواستها دو ثانیه فاصله میگذارد و--random-waitاین زمان را تصادفی تغییر میدهد. - گزینه
--limit-rate=500kسرعت دانلود را محدود میکند. - گزینه
--no-parentجلوی بالا رفتن به پوشههای والد را میگیرد و-A pdfفقط پسوندهای مشخصشده را دریافت میکند.
wget بهطور پیشفرض از قاعدههای robots.txt پیروی میکند؛ این رفتار را خاموش نکنید. اینکه کدام داده در چه شرایطی قابل جمعآوری است را در نوشته آیا اسکرپینگ وب قانونی است؟ توضیح دادهایم.
در پروژههایی که درخواستهای زیادی لازم دارند، بهجای انباشتن ترافیک روی یک IP، پخش کردن نشانیها با پروکسی چرخشی هم خطر مسدود شدن را کم میکند و هم بار متعادلتری بر سایت مقصد میگذارد. برای نیازهای گستردهتر راهکارهای استخراج داده ما را ببینید.
پرسشهای متداول
wget یا cURL؟
برای دانلود فایل، آینهسازی و دریافت بازگشتی wget کاربردیتر است؛ برای درخواستهای API، روشهای ویژه HTTP و پروکسی SOCKS توانایی cURL بیشتر است. هر دو پروکسی HTTP را از متغیرهای محیطی یکسانی میخوانند، به همین دلیل تنظیمی که یک بار تعریف شود در هر دو ابزار کار میکند.
تنظیم پروکسی بر برنامههای دیگر اثر میگذارد؟
پروکسیای که با متغیر محیطی تعریف شود، بر هر برنامهای که از همان پوسته اجرا شود و این متغیرها را بخواند (مانند cURL، pip و git) اثر میگذارد. روشهای .wgetrc و -e فقط بر wget اثر میگذارند.
میتوانم بدون ذخیره رمز عبور از پروکسی استفاده کنم؟
بله. اگر از پنل ارائهدهنده پروکسی، نشانی IP سرور خود را مجاز کنید، نام کاربری و رمز عبور لازم نیست؛ نشانی فقط به شکل http://server:port نوشته میشود. برای سرورهای دارای IP ثابت پاکیزهترین روش همین است.
با wget میتوانم در هر درخواست IP متفاوتی بگیرم؟
خود wget چرخش انجام نمیدهد. دو راه وجود دارد: استفاده از پروکسی چرخشی (یک نشانی، IP خروجی متفاوت در هر اتصال) یا دادن پروکسی متفاوت به هر فراخوانی با -e https_proxy= در یک اسکریپت.
از طریق پروکسی میتوانم از FTP دانلود کنم؟
اگر متغیر ftp_proxy تعریف شده باشد، wget نشانیهای FTP را از طریق پروکسی HTTP دریافت میکند؛ پروکسی باید از این کاربرد پشتیبانی کند. امروزه چون منابع FTP کمتر شدهاند، بیشتر بستههای پروکسی بر HTTP و HTTPS متمرکزند.
جمعبندی
برای استفاده از wget با پروکسی سه راه وجود دارد: متغیرهای محیطی برای آزمون سریع، گزینه -e برای استفاده یکباره در اسکریپت و فایل .wgetrc برای استفاده همیشگی. فراموش نکنید برای نشانیهای HTTPS متغیر https_proxy را تعریف کنید، اطلاعات ورود را امن نگه دارید، در دانلودهای انبوه سرعت را محدود کنید و وقتی SOCKS لازم است به cURL بروید.




