قسّم الكتالوج حسب المتجر
لكل متجر طابور طلباته وحصته من قائمة البروكسي. الأسواق الكبيرة تأخذ الحصة الأكبر.
تعرض المتاجر أسعارًا مختلفة لكل منطقة وتحظر من يسأل كثيرًا من عنوان واحد. أداة تتبع الأسعار على Advanced.name توزّع طلباتها على عشرات الآلاف من عناوين IPv4 وتسأل كل متجر من منطقة مشتريه.
تزور الأداة الصفحات نفسها كل ساعة. هذا النمط تحديدًا هو ما يُحظر، وعلى المجموعة أن تخفيه.
عنوان IP مختلف في كل زيارة للمنتج نفسه
في الباقة رقم 4 هناك 30,000 عنوان: صفحة المنتج ترى العنوان نفسه مرة في الشهر
الأسعار كما يراها المشترون المحليون
مجموعات أوروبا ورابطة الدول المستقلة والصين؛ والمزيج العالمي للولايات المتحدة وغيرها
آلاف المنتجات تُفحص كل ساعة
حتى 2,500 خيط في الباقة رقم 4، و5,000 في الباقة رقم 6
صفحات بالصور والسكربتات، لا JSON فقط
لا حد للحركة: اجلب الصفحات كاملة بقدر ما يتطلب الجدول
عشرة آلاف منتج في الساعة تكفيها الباقة رقم 3؛ ومراقبة سوق إلكتروني كامل تحتاج الباقة رقم 4 أو أكبر.
لكل متجر طابور طلباته وحصته من قائمة البروكسي. الأسواق الكبيرة تأخذ الحصة الأكبر.
خذ العنوان التالي لكل طلب، وأعد المحاولة مرتين من عنوان آخر، وسجّل السعر مع عنوان IP الذي جلبه.
تخرج العناوين من المجموعة حين تقدم. الرابط يعيد دائمًا المجموعة الحالية، فأعد قراءته بمؤقت.
املأ products.txt بروابط المنتجات واضبط COUNTRY. يُجلب كل منتج عبر البروكسي التالي، ويُستخرج السعر ويُكتب في prices.csv. عدّل PRICE_RE حسب ترميز المتجر. جرّبه أولًا على قائمة البروكسي المجانية.
#!/usr/bin/env python3
"""Price monitor for Advanced.name proxies.
Fetches product pages through proxies from the buyer's country and pulls the
price out of each page. One request per product goes through the next proxy, so
a shop sees the same address rarely. Standard library only. python3 prices.py
"""
# ================================ CONFIG ====================================
CSV_URL = "https://get.advanced.name/YOUR_LIST_ID.csv" # CSV export link from your dashboard
COUNTRY = "DE" # buyers' country: prices are read as local shoppers see them
MIN_SPEED = 3
PRODUCTS_FILE = "products.txt" # one product URL per line
PRICE_RE = r'"price"\s*:\s*"?([0-9][0-9.,]*)' # regex, group 1 = the price
OUT_FILE = "prices.csv" # url;price;proxy;country is written here
THREADS = 40
TIMEOUT = 20
RETRIES = 3
# ============================================================================
import csv
import io
import itertools
import re
import sys
import threading
import urllib.request
from concurrent.futures import ThreadPoolExecutor, as_completed
COL_IP, COL_PORT, COL_COUNTRY, COL_SPEED = 0, 1, 2, 3
UA = "Mozilla/5.0 (compatible; price-monitor/1.0)"
PRICE = re.compile(PRICE_RE)
def load_proxies():
raw = urllib.request.urlopen(CSV_URL, timeout=30).read().decode("utf-8", "replace")
pool = []
for row in csv.reader(io.StringIO(raw), delimiter=";"):
if len(row) <= COL_SPEED or not row[COL_PORT].strip().isdigit():
continue
if COUNTRY and row[COL_COUNTRY].strip().upper() != COUNTRY.upper():
continue
if int(row[COL_SPEED] or 0) < MIN_SPEED:
continue
pool.append(row[COL_IP].strip() + ":" + row[COL_PORT].strip())
return pool
def main():
proxies = load_proxies()
if not proxies:
sys.exit("No proxies for COUNTRY=%r." % COUNTRY)
with open(PRODUCTS_FILE, encoding="utf-8") as fh:
products = [line.strip() for line in fh if line.strip() and not line.startswith("#")]
print("proxies: %d (%s), products: %d" % (len(proxies), COUNTRY, len(products)))
rotation = itertools.cycle(proxies)
lock = threading.Lock()
def grab(url):
for _ in range(RETRIES):
with lock:
proxy = next(rotation)
handler = urllib.request.ProxyHandler({"http": "http://" + proxy, "https": "http://" + proxy})
req = urllib.request.Request(url, headers={
"User-Agent": UA, "Accept-Language": COUNTRY.lower() + "," + COUNTRY.upper()})
try:
html = urllib.request.build_opener(handler).open(req, timeout=TIMEOUT).read().decode("utf-8", "replace")
except Exception:
continue
match = PRICE.search(html)
return (match.group(1) if match else "not found"), proxy
return "unreachable", ""
rows = []
with ThreadPoolExecutor(max_workers=THREADS) as pool:
futures = {pool.submit(grab, u): u for u in products}
for fut in as_completed(futures):
url = futures[fut]
price, proxy = fut.result()
rows.append((url, price, proxy, COUNTRY))
print("%-9s %s" % (price, url[:60]))
with open(OUT_FILE, "w", encoding="utf-8", newline="") as out:
writer = csv.writer(out, delimiter=";")
writer.writerow(["url", "price", "proxy", "country"])
writer.writerows(rows)
print("written %s (%d rows)" % (OUT_FILE, len(rows)))
if __name__ == "__main__":
main()
اجلب كل صفحة منتج عبر البروكسي التالي وخذ السعر من كتلة JSON-LD أو من عقدة السعر؛ السكربت أعلاه يستخدم تعبيرًا نمطيًا تضبطه لكل متجر. أرسل Accept-Language وملف تعريف ارتباط العملة الخاص بالمنطقة مع IP المحلي، وإلا فقد يحولك المتجر إلى سوق أخرى.
جدول حسب الضغط: المخزون كل ساعة، والأسعار مرتين في اليوم. احفظ رمز HTTP مع كل سعر، فتخبرك موجة من 403 من متجر واحد أن تبطئ هناك لا في كل مكان.
خدمات تتبع الأسعار وأدوات السحب بلا كود (Octoparse وWeb Scraper) تقبل قائمة بروكسي في الإعدادات: الصق ملف ip:port نفسه. حتى IMPORTXML في Google Sheets يمكن أن يعمل خلف وسيط بروكسي صغير للفحوص الخفيفة.
حافظ على المجموعة محدّثة بـأداة فحص البروكسي وجرّب التدفق على قائمة البروكسي المجانية قبل التوسع إلى الكتالوج كاملًا.



المرور على الكتالوج كل ساعة يعوّض تكلفته على باقة غير محدودة. أما المتاجر شديدة الحماية وأسعار المدن فتحتاج عناوين سكنية.
الكتالوج كل ساعةالخيار الأنسب
مع الفحص كل ساعة، تلتقي صفحة المنتج بعنوان IP نفسه مرة في الشهر تقريبًا. والصفحات الكاملة لا ترفع الفاتورة.
$990 شهريًاأو $4.20 للساعة
متاجر صارمة
عنوان IP منزلي من بلد المتجر مع كل طلب. للمواقع التي تعرض لعناوين القوائم رمز تحقق بدل السعر.
من $0.49 للغيغابايت1 غيغابايت بسعر $0.85
أسعار المدن
المدينة والمنطقة في سلسلة الاتصال. يعرض المتجر السعر والتوصيل كما يراهما مشترٍ في تلك المدينة.
من $1.39 للغيغابايت1 غيغابايت بسعر $2.29
اختر الباقة، وخذ الساعة المجانية، ومرّر أداة التتبع على الكتالوج كله.