نحوه راهاندازی پروکسیهای دیتاسنتری Smartproxy روی لینوکس برای پایش قیمت با پایتون
درخواستهای زمانبندیشدهٔ پایش قیمت با پایتون را روی لینوکس از طریق پروکسیهای دیتاسنتری Smartproxy مسیردهی کنید، با نگهداشتن اعتبارنامهها بیرون از کد، تلاشهای مجدد و عقبنشینی، راهنمای چرخش، ثبت CSV و زمانبندی cron.
مرور کلی
Smartproxy یک شبکهٔ پروکسی مناسب برای مبتدیان با استخرهای residential و datacenter است که از طریق HTTP و SOCKS5 قابل دسترسی هستند و بر اساس مدل هزینهٔ ثابت ماهانه صورتحساب میشوند. این آموزش استخر datacenter آن را به یک کار مشخص و رایج روی لینوکس اختصاص میدهد: پایش زمانبندیشدهٔ قیمت با پایتون.
پایش قیمت با IPهای دیتاسنتر خوب جور درمیآید. درخواستها سریع هستند، هدفها صفحات محصول عمومیاند و بار کاری بیشتر خواندنی است. اگر خردهفروش خاصی شروع به مسدود کردن محدودههای دیتاسنتر کند، همان اسکریپت روی استخر residential اجرا میشود — فقط endpoint و اعتبارنامهها تغییر میکنند.
در پایان خواهید داشت:
- اعتبارنامههایی که بیرون از کد منبع شما ذخیره شدهاند
- یک درخواست پروکسی تأییدشده از خط فرمان
- یک اسکریپت پایتون که صفحات محصول را از طریق پروکسی با تلاش مجدد و عقبنشینی واکشی میکند
- قیمتهایی که با برچسب زمانی به یک فایل CSV افزوده میشوند
- یک ورودی cron که کار را طبق زمانبندی اجرا میکند
برای هیچکدام از اینها به رابط گرافیکی نیاز ندارید. Smartproxy افزونههای مرورگر هم ارائه میدهد، اما یک کار headless روی لینوکس فقط به host، port، username و password از داشبورد شما نیاز دارد.
پیشنیازها
- یک میزبان لینوکس — دستورات زیر روی خانوادههای Debian/Ubuntu و Fedora/RHEL کار میکنند
- Python 3.9 یا جدیدتر
- یک حساب Smartproxy با دسترسی پروکسی datacenter
- host، port، username و password پروکسی که در داشبورد Smartproxy شما فهرست شدهاند
دیتاسنتر یا Residential؟
هر دو نوع استخر در کد بهصورت یکسان پیکربندی میشوند، بنابراین تصمیم دربارهٔ سایت هدف است، نه دربارهٔ ابزار.
| عامل | دیتاسنتر | Residential |
|---|---|---|
| سرعت بهازای هر درخواست | سریع | متوسط |
| هزینه بهازای هر GB | کمتر | بیشتر |
| ریسک مسدود شدن در خردهفروشان بزرگ | بیشتر | کمتر |
| بهترین تناسب | خواندنهای پرحجم از سایتهای مقاوم | سایتهای محافظتشده و قیمتگذاری جغرافیایی دقیق |
قواعد سرانگشتی:
- با datacenter شروع کنید، چون راه ارزانتر و سریعتری برای اثبات کارکرد parser شماست.
- یک هدف سرسخت را به residential منتقل کنید، نه اینکه کل کار را مهاجرت دهید.
- طرح پروکسی و احراز هویت را بین استخرها یکسان نگه دارید تا جابهجایی یک تغییر پیکربندی باشد، نه بازنویسی.
مراحل
مرحله ۱ — اعتبارنامهها را export کنید و endpoint را تأیید کنید
چهار مقدار داشبورد خود را بهعنوان متغیرهای محیطی برای نشست shell فعلی تنظیم کنید. جاینگهدارها را با مقادیر خودتان جایگزین کنید.
export SMART_HOST=\"<host-from-dashboard>\"
export SMART_PORT=\"<port-from-dashboard>\"
export SMART_USER=\"<username>\"
export SMART_PASS=\"<password>\"
یک درخواست تکی را از طریق پروکسی اجرا کنید. ارسال اعتبارنامهها با -U از مشکلات مربوط به کاراکترهای خاص در password جلوگیری میکند.
curl -sS --max-time 20 -x \"http://${SMART_HOST}:${SMART_PORT}\" -U \"${SMART_USER}:${SMART_PASS}\" https://api.ipify.org
پاسخ باید یک آدرس IP باشد که IP خود سرور شما نیست. اگر بهجای آن خطای 407 دیدید، به جدول عیبیابی در انتها بروید.
مرحله ۲ — پروژه را ایجاد کنید و اسرار را به یک فایل منتقل کنید
- یک دایرکتوری و یک محیط مجازی ایجاد کنید.
requestsبههمراهpython-dotenvرا نصب کنید، که فایل.envرا در زمان اجرا در محیط بارگذاری میکند.
mkdir -p ~/price-monitor && cd ~/price-monitor
python3 -m venv .venv && source .venv/bin/activate
pip install requests python-dotenv
فایل اسرار را ایجاد کنید و مجوزهای آن را محدود کنید. این فایل هرگز نباید commit شود.
# ~/price-monitor/.env
SMART_HOST=<host-from-dashboard>
SMART_PORT=<port-from-dashboard>
SMART_USER=<username>
SMART_PASS=<password>
chmod 600 .env
cat > .gitignore <<'EOF'
.env
.venv/
EOF
مرحله ۳ — آدرس پروکسی را در پایتون بسازید
آدرس را یکبار بسازید و دوباره استفاده کنید. quote کردن username و password با quote() از کاراکترهایی مانند @، : یا # محافظت میکند که در غیر این صورت تجزیه URL را میشکنند.
# ~/price-monitor/proxy_config.py
import os
from urllib.parse import quote
from dotenv import load_dotenv
load_dotenv()
def proxy_url(scheme='http'):
user = quote(os.environ['SMART_USER'], safe='')
password = quote(os.environ['SMART_PASS'], safe='')
host = os.environ['SMART_HOST']
port = os.environ['SMART_PORT']
return f'{scheme}://{user}:{password}@{host}:{port}'
PROXIES = {'http': proxy_url(), 'https': proxy_url()}
اگر endpoint شما برای ترافیک HTTPS از پورت دیگری استفاده میکند، هر دو کلید را جداگانه تنظیم کنید، نه اینکه فرض کنید پورت مشترک است.
مرحله ۴ — صفحهای را از طریق پروکسی با تلاش مجدد واکشی کنید
درخواست را در یک حلقهٔ کوچک تلاش مجدد بپیچید. عقبنشینی نمایی مانع از کوبیدن مداوم روی هدفی میشود که به شما محدودیت نرخ اعمال میکند.
# ~/price-monitor/fetch_price.py
import time
import requests
from proxy_config import PROXIES
HEADERS = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/124.0 Safari/537.36',
'Accept-Language': 'en-US,en;q=0.9',
}
def fetch(url, retries=3, timeout=25):
last_error = None
for attempt in range(1, retries + 1):
try:
response = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=timeout)
if response.status_code == 200:
return response.text
last_error = 'HTTP %s' % response.status_code
except requests.RequestException as exc:
last_error = str(exc)
time.sleep(2 ** attempt)
raise RuntimeError('Failed to fetch %s: %s' % (url, last_error))
if __name__ == '__main__':
html = fetch('https://example.com/product/123')
print(html[:500])
مرحله ۵ — قیمت را استخراج کنید و به CSV بیفزایید
پارسرهای HTML مانند BeautifulSoup یا selectolax استخراج مقاومتری ارائه میدهند، اما یک regex برای اعتبارسنجی خط لوله پیش از سرمایهگذاری روی selectorها کافی است.
# ~/price-monitor/parse_price.py
import csv
import datetime
import re
import sys
from fetch_price import fetch
def parse_price(html):
# Replace this pattern with a selector that matches the target site's markup.
match = re.search(r'data-price=([0-9.]+)', html)
return float(match.group(1)) if match else None
def main(url):
price = parse_price(fetch(url))
with open('prices.csv', 'a', newline='', encoding='utf-8') as handle:
writer = csv.writer(handle)
writer.writerow([datetime.datetime.now(datetime.UTC).isoformat(), url, price])
if __name__ == '__main__':
main(sys.argv[1] if len(sys.argv) > 1 else 'https://example.com/product/123')
مرحله ۶ — تصمیم بگیرید چرخش برای endpoint شما چگونه کار کند
رفتار چرخش به endpointی که به شما داده شده بستگی دارد، بنابراین پیش از هر فرضی داشبورد خود را بررسی کنید:
- اگر پورت در هر درخواست IP خروجی را میچرخاند، فراخوانی دوبارهٔ
fetch()کافی است — هر اتصال جدید میتواند از IP متفاوتی خارج شود. - اگر پورت یک نشست sticky را نگه میدارد، بین پورتهای فهرستشده در داشبورد بچرخید و برای هر worker یک پورت نگه دارید.
- فقط زمانی دوباره از همان
requests.Session()استفاده کنید که نشست sticky میخواهید؛ یک نشست تازه بهازای هر درخواست، پیشفرض امنتری برای پایش است.
برای تأیید چرخش، چند بار پشتسرهم endpoint مربوط به IP را درخواست کنید.
def check_ip():
return fetch('https://api.ipify.org').strip()
if __name__ == '__main__':
for _ in range(5):
print(check_ip())
مرحله ۷ — همروندی متعادل اضافه کنید
یک thread pool فهرست طولانی URLها را کوتاهتر میکند، اما همروندی سریعترین راه برای مسدود شدن هم هست. کوچک شروع کنید و تعداد worker را فقط تا زمانی که نرخ خطا ثابت میماند افزایش دهید.
| workerهای همروند | زمان منطقی بودن |
|---|---|
| ۱ تا ۳ | اولین اجرا روی یک هدف جدید |
| ۴ تا ۶ | اجرای پایدار datacenter، بدون پاسخهای محدودیت نرخ |
| ۸ یا بیشتر | فقط پس از تست، و معمولاً با IPهای residential |
from concurrent.futures import ThreadPoolExecutor, as_completed
from fetch_price import fetch
urls = [f'https://example.com/product/{sku}' for sku in range(1, 6)]
with ThreadPoolExecutor(max_workers=5) as pool:
futures = {pool.submit(fetch, url): url for url in urls}
for future in as_completed(futures):
url = futures[future]
try:
print(url, len(future.result()))
except Exception as exc:
print(url, 'failed:', exc)
مرحله ۸ — کار را با cron زمانبندی کنید
crontab خود را ویرایش کنید و یک خط اضافه کنید. cd مهم است چون اسکریپت به قرار داشتن فایل .env در دایرکتوری کاری وابسته است.
crontab -e
0 */6 * * * cd /home/<user>/price-monitor && .venv/bin/python parse_price.py https://example.com/product/123 >> run.log 2>&1
از مسیر مطلق Python محیط مجازی استفاده کنید. python خالی زیر cron اغلب به مفسر سیستمی اشاره میکند و بستههای نصبشدهٔ شما را نمیبیند.
استفاده از SOCKS5 بهجای HTTP
Smartproxy در کنار HTTP از SOCKS5 هم پشتیبانی میکند و جابهجایی یک تغییر یکخطی است. پورت SOCKS5 را در داشبورد خود تأیید کنید، چون ممکن است با پورت HTTP متفاوت باشد.
pip install 'requests[socks]'
PROXIES = {'http': proxy_url('socks5'), 'https': proxy_url('socks5')}
SOCKS5 زمانی مفید است که میخواهید resolution DNS هم از طریق پروکسی انجام شود، یا وقتی ابزار دیگری در خط لولهٔ شما فقط به SOCKS5 حرف میزند.
عیبیابی
| نشانه | علت احتمالی | چهکار کنید |
|---|---|---|
407 Proxy Authentication Required |
اعتبارنامه اشتباه یا کهنه، یا password با کاراکترهای خاص escapeنشده | مقادیر را از داشبورد دوباره کپی کنید، با دستور curl -U از مرحله ۱ تأیید کنید، و در پایتون به quote() تکیه کنید |
403 یا صفحهٔ CAPTCHA |
هدف محدودههای datacenter را مسدود میکند، یا هدرها خودکار به نظر میرسند | اجرا را کند کنید، هدرهای مرورگر واقعگرایانه بفرستید و آن هدف را به استخر residential منتقل کنید |
429 Too Many Requests |
workerهای همروند بیش از حد زیاد | max_workers را کاهش دهید، عقبنشینی نمایی را نگه دارید و بین دستهها وقفه بیندازید |
| timeout اتصال در هر درخواست | host یا port اشتباه، یا ترافیک خروجی روی آن پورت مسدود است | بررسی curl را دوباره اجرا کنید؛ ufw، iptables یا هر سیاست خروج سازمانی برای پورت پروکسی را مرور کنید |
| با یک IP checker کار میکند اما روی هدف شکست میخورد | محافظت ضدربات مخصوص آن سایت | یک درخواست را در یک نشست مرورگر عادی تست کنید، هدرها را تنظیم کنید و انتظار داشته باشید برخی اهداف به IPهای residential نیاز داشته باشند |
CERTIFICATE_VERIFY_FAILED |
بستهٔ CA قدیمی روی میزبان | ca-certificates و بستههای محیط مجازی را بهروزرسانی کنید، نه اینکه تأیید را غیرفعال کنید |
خلاصه
- استخر datacenter Smartproxy یک پیشفرض عملی برای پایش قیمت پرحجم و فقطخواندنی روی لینوکس است.
- host، port، username و password را در یک فایل
.envبا مجوزهای600نگه دارید و آنها را باpython-dotenvبارگذاری کنید. - پیش از قرار دادن اعتبارنامهها در URL پروکسی، آنها را quote کنید، وگرنه کاراکترهای خاص تجزیه را میشکنند.
- همیشه timeout درخواست را تنظیم کنید، با عقبنشینی دوباره تلاش کنید، و همروندی را پایین نگه دارید تا نرخ خطا ثابت کند افزایش آن امن است.
- داشبورد خود را بررسی کنید تا بدانید endpoint شما در هر درخواست میچرخد یا نشست sticky را نگه میدارد، سپس اجرا را بر آن اساس طراحی کنید.
- یک هدف مسدودشدهٔ تکی را به استخر residential تغییر دهید، نه اینکه کار را از نو بسازید، و از SOCKS5 فقط زمانی استفاده کنید که برای DNS یا دلایل ابزاری به آن نیاز دارید.