Виберіть регіон
Google.de знімайте через Європу, Яндекс через СНД, Baidu через Китай. Мікс світу покриває решту і дає найбільші пули.
Пошуковики показують видачу залежно від регіону, тож чекеру позицій потрібна IP потрібної країни на кожну пачку запитів. Resi Core дає домашню адресу будь-якої з 200+ країн просто в рядку підключення, а безлімітні пакети з фільтром за країною закривають великі ядра. Окремо розібрано знімання ШІ-відповідей Google: вони теж залежать від країни й міста.
Позиції залежать від того, звідки прийшов запит. Пул має відповісти на це питання першим.
Адреси з країни, яку ви відстежуєте
Resi Core: країна задається в логіні; на пакетах стовпчик країни в CSV-вивантаженні
Новий IP на кожну пачку запитів
Resi Core міняє адресу на кожен запит, у пакетах приблизно третина адрес змінюється щодня
Досить паралельних запитів для великого семантичного ядра
Потоки на Resi без ліміту, на пакетах від 500 до 5 000
Працює з чекером, який у вас уже є
Resi за логіном і паролем у рядку, пакети за IP; HTTP і SOCKS5 приймають A-Parser, Key Collector і Rank Tracker
Сторінка видачі важить мало, тому гігабайт іде на тисячі запитів. Ціна за ГБ падає з обсягом замовлення.
| Обсяг замовлення | Resi Core | Resi Prime |
|---|---|---|
| від 1 ГБ | $0.85 | $2.29 |
| від 10 ГБекономія 7% | $0.79 | $2.09 |
| від 50 ГБ | $0.72 | $1.95 |
| від 100 ГБ | $0.65 | $1.75 |
| від 500 ГБ | $0.57 | $1.55 |
| від 1000 ГБ | $0.49 | $1.39 |
Ціни в доларах США за 1 ГБ. Трафік купується цілою кількістю гігабайтів, від 1 ГБ.
Пул
Економія 7% ($1.50) проти ціни від 1 ГБ
Ще 25 ГБ, і кожен гігабайт вийде по $0.72
Купити цей обсягГігабайти можна витрачати 3 місяці від дати покупки, потім залишок списується.
Google.de знімайте через Європу, Яндекс через СНД, Baidu через Китай. Мікс світу покриває решту і дає найбільші пули.
Візьміть CSV-вивантаження і лишіть рядки, де стовпчик країни збігається з ринком, який ви відстежуєте; готовий збирач запише окремий файл ip:port для кожної країни.
Чекери позицій беруть файл з проксі або URL. Поставте оновлення раз на 10 хвилин, і список сам лишатиметься актуальним.
Задайте DOMAIN і COUNTRY, ключі покладіть у keywords.txt. Скрипт запитує пошуковик через проксі цієї країни і пише позицію вашого домену в CSV. Давайте йому чистий пул після чекера проксі.
#!/usr/bin/env python3
"""Search-position checker for Advanced.name proxies.
Reads the CSV proxy export, keeps one country, then asks a search engine for each
keyword through a proxy from that country and reports where your domain sits in
the results. Standard library only. Edit CONFIG and run: python3 rank.py
"""
# ================================ CONFIG ====================================
CSV_URL = "https://get.advanced.name/YOUR_LIST_ID.csv" # CSV export link from your dashboard
COUNTRY = "DE" # ISO 3166-1 alpha-2: positions are read from this country
MIN_SPEED = 3 # keep proxies with speed >= this value
DOMAIN = "example.com" # the domain whose position you track
KEYWORDS_FILE = "keywords.txt" # one keyword per line
SEARCH_URL = "https://www.bing.com/search?q={q}&count=50&setlang={cc}" # {q}=keyword, {cc}=country
OUT_FILE = "positions.csv" # keyword;position;proxy is written here
TIMEOUT = 20
# ============================================================================
import csv
import io
import re
import sys
import urllib.parse
import urllib.request
COL_IP, COL_PORT, COL_COUNTRY, COL_SPEED = 0, 1, 2, 3
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36"
HREF = re.compile(r'href="https?://([^/"]+)', re.I)
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 position(html, domain):
"""First place the domain shows up among the result links, or 0 if absent."""
rank, seen = 0, set()
for host in HREF.findall(html):
host = host.lower()
if "bing.com" in host or "microsoft.com" in host or host in seen:
continue
seen.add(host)
rank += 1
if host == domain or host.endswith("." + domain):
return rank
return 0
def main():
proxies = load_proxies()
if not proxies:
sys.exit("No proxies for COUNTRY=%r." % COUNTRY)
with open(KEYWORDS_FILE, encoding="utf-8") as fh:
keywords = [line.strip() for line in fh if line.strip()]
print("proxies: %d (%s), keywords: %d" % (len(proxies), COUNTRY, len(keywords)))
with open(OUT_FILE, "w", encoding="utf-8", newline="") as out:
writer = csv.writer(out, delimiter=";")
writer.writerow(["keyword", "position", "proxy"])
for i, keyword in enumerate(keywords):
proxy = proxies[i % len(proxies)]
url = SEARCH_URL.format(q=urllib.parse.quote(keyword), cc=COUNTRY.lower())
handler = urllib.request.ProxyHandler({"http": "http://" + proxy, "https": "http://" + proxy})
req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Language": COUNTRY.lower()})
try:
html = urllib.request.build_opener(handler).open(req, timeout=TIMEOUT).read().decode("utf-8", "replace")
pos = position(html, DOMAIN.lower())
except Exception as exc:
pos = "err: %s" % exc.__class__.__name__
writer.writerow([keyword, pos, proxy])
print("%-40s %s" % (keyword[:40], pos))
print("written %s" % OUT_FILE)
if __name__ == "__main__":
main()
Вставте рядок Resi з кабінету, задайте DOMAIN і покладіть запити в keywords.txt. Скрипт відкриває видачу в справжньому Chromium через проксі, чекає, поки довантажиться ШІ-блок, і пише в CSV, чи є блок, які домени він цитує і чи є серед них ваш. Вікно cookie в країнах ЄС він закриває сам, капчу й помилки проксі позначає окремим рядком. Google змінює верстку, тому підпис блоку винесено в LABELS.
#!/usr/bin/env python3
"""AI Overview tracker for Advanced.name residential proxies.
Opens Google results for every keyword through a Resi Core or Resi Prime line
in a real Chromium, because the AI block is drawn by JavaScript. Records
whether the page shows the AI block and which domains it cites.
Setup: pip install playwright && python -m playwright install chromium
"""
# ================================ CONFIG ====================================
PROXY = "res.advanced.name:9000:USER-type-residential-country-us:PASS" # host:port:login:password line from your dashboard
DOMAIN = "example.com" # the domain you want to see among the cited sources
KEYWORDS_FILE = "keywords.txt" # one keyword per line
SEARCH_URL = "https://www.google.com/search?q={q}&hl={hl}&gl={gl}" # {q}=keyword
HL = "en" # interface language of the results page
GL = "us" # country of the results, keep it equal to the country in the login
LABELS = "AI Overview|AI Mode" # heading text of the AI block, separated by |
CONSENT = "Reject all|Accept all" # cookie banner buttons in EU countries, in the HL language
OUT_FILE = "ai_overview.csv" # keyword;ai_block;cited;your_domain is written here
WAIT_MS = 4000 # time for the AI block to finish drawing
HEADLESS = True # set False to watch the browser
# ============================================================================
import csv
import sys
import urllib.parse
from playwright.sync_api import sync_playwright
FIND_BLOCK = """(labels) => {
const heads = [...document.querySelectorAll('h1,h2,h3,div,span')]
.filter(e => e.children.length === 0 && labels.includes(e.textContent.trim()));
if (!heads.length) return null;
let box = heads[0];
for (let i = 0; i < 8 && box.parentElement; i++) {
box = box.parentElement;
const links = [...box.querySelectorAll('a[href^="http"]')];
if (links.length >= 2 && box.innerText.length > 200) return links.map(a => new URL(a.href).hostname);
}
return [];
}"""
def proxy_of(line):
host, port, user, password = line.strip().split(":", 3)
return {"server": "http://%s:%s" % (host, port), "username": user, "password": password}
def bare(host):
host = host.lower()
return host[4:] if host.startswith("www.") else host
def main():
keywords = [k.strip() for k in open(KEYWORDS_FILE, encoding="utf-8") if k.strip()]
labels = [x.strip() for x in LABELS.split("|") if x.strip()]
consent = [x.strip() for x in CONSENT.split("|") if x.strip()]
rows = []
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=HEADLESS, proxy=proxy_of(PROXY))
page = browser.new_page(locale=HL)
for kw in keywords:
url = SEARCH_URL.format(q=urllib.parse.quote_plus(kw), hl=HL, gl=GL)
try:
resp = page.goto(url, wait_until="domcontentloaded", timeout=60000)
if resp is None or resp.status >= 400:
status = "http %s" % (resp.status if resp else "none")
print("%-40s %s" % (kw[:40], status), file=sys.stderr)
rows.append([kw, status, "", ""])
continue
for name in consent:
button = page.get_by_role("button", name=name)
if button.count():
button.first.click()
page.wait_for_load_state("domcontentloaded")
break
if "/sorry/" in page.url:
print("%-40s captcha: change the session id in the login" % kw[:40], file=sys.stderr)
rows.append([kw, "captcha", "", ""])
continue
page.wait_for_timeout(WAIT_MS)
hosts = page.evaluate(FIND_BLOCK, labels)
except Exception as exc:
print("%-40s error: %s" % (kw[:40], str(exc).splitlines()[0]), file=sys.stderr)
rows.append([kw, "error", "", ""])
continue
if hosts is None:
print("%-40s no AI block" % kw[:40])
rows.append([kw, "no", "", ""])
continue
cited = sorted({bare(h) for h in hosts if "google." not in h})
mine = any(h == DOMAIN or h.endswith("." + DOMAIN) for h in cited)
print("%-40s AI block, %d sources, %s %s" % (kw[:40], len(cited), DOMAIN, "cited" if mine else "not cited"))
rows.append([kw, "yes", " ".join(cited), "yes" if mine else "no"])
browser.close()
with open(OUT_FILE, "w", encoding="utf-8", newline="") as f:
out = csv.writer(f, delimiter=";")
out.writerow(["keyword", "ai_block", "cited", "your_domain"])
out.writerows(rows)
print("saved", OUT_FILE)
if __name__ == "__main__":
main()
В A-Parser і Key Collector вставте список ip:port у поле проксі і задайте інтервал перевірки так, щоб один ключ потрапляв на одну адресу не частіше ніж раз на добу. Rank Tracker та схожі десктопні програми читають файл з проксі; вкажіть їм список, який збирач пише для кожної країни.
Позиції залежать від того, звідки прийшов запит, тож тримайте окремий список для кожного ринку: по екземпляру трекера на країну, і кожному лише адреси цієї країни.
Скрипт вище запитує пошуковик через проксі потрібної країни і записує місце вашого домену. Разом із проксі передавайте параметри мови й регіону пошуковика: адреса задає країну, параметри задають місто.
Перед запуском перевірте пул чекером проксі; для легкої ручної проби підійде безкоштовний список проксі. Вступ про регіональну видачу з'явиться в статтях.
Над звичайною видачею Google дедалі частіше ставить ШІ-блок: коротку відповідь з посиланнями на джерела. Частина кліків іде туди, тому важливо знати, чи потрапив ваш сайт у джерела й за якими запитами блоку немає взагалі. Блок збирається під розташування користувача: за одним запитом Берлін і Мюнхен можуть побачити різні джерела.
Звичайний парсер видачі цього блоку не бачить: Google домальовує його JavaScript уже після завантаження сторінки. Потрібен справжній браузер, наприклад Chromium через Playwright, і домашня IP потрібної країни. Адреси зі спільних списків на такій видачі часто отримують капчу, тому тут працюють Resi Core і Resi Prime.
Для знімання за країною вистачить Resi Core з кодом країни в логіні. Якщо клієнту важливе місто, беріть Resi Prime з містом у рядку й фіксованою сесією на пачку запитів: тоді вся пачка піде з однієї адреси цього міста.
Знімайте ядро раз на добу або раз на тиждень: ШІ-блок змінюється повільніше за звичайні позиції. На кожен запит пишіть дату, країну або місто, чи є блок, які домени він цитує і чи є серед них ваш. За місяць видно, які сторінки ШІ бере у відповідь, а які випали.
Другий скрипт вище пише саме ці поля в CSV. Звичайні позиції в тій самій країні знімає перший скрипт, і обидва звіти сходяться за запитами.

Видачу за країною знімайте через Resi Core, видачу міста через Resi Prime, а великі ядра щодня дешевше ганяти на безлімітному пакеті.
Видача за країноюНайкращий вибір
Домашня IP потрібної країни на кожен запит. Сторінка видачі важить мало, тому гігабайт іде на тисячі запитів.
від $0.49 за ГБ1 ГБ за $0.85
Видача міста
Місто й регіон у рядку підключення дають видачу, яку бачить користувач з цього міста.
від $1.39 за ГБ1 ГБ за $2.29
Великі ядра
Десятки тисяч запитів на добу без лічильника трафіку. Країну ринку відбираєте за стовпчиком CSV-вивантаження.
$378 на місяцьабо $2.10 за годину
Візьміть 1 ГБ Resi Core, задайте країну в рядку й запустіть чекер на живих адресах.