Escolha a região
Acompanhe o Google.de pela Europa, o Yandex pela CEI e o Baidu pela China. O World MIX cobre o resto e tem os maiores pools.
Os buscadores mostram resultados por região, então um rank checker precisa de um IP do país certo para cada lote de consultas. O Resi Core dá um endereço residencial em qualquer um de mais de 200 países direto na string de conexão, enquanto os pacotes ilimitados com filtro de país cobrem listas grandes de palavras-chave. Uma seção à parte trata do acompanhamento das respostas de IA do Google, que também dependem do país e da cidade.
As posições dependem de onde vem a consulta. O pool precisa responder isso primeiro.
Endereços do país que você acompanha
Resi Core: o país vai no login; nos pacotes, uma coluna de país no CSV exportado
Um IP novo para cada lote de consultas
O Resi Core troca o endereço a cada requisição, e os pacotes renovam cerca de um terço dos endereços por dia
Consultas paralelas para uma lista grande de palavras-chave
Sem limite de threads no Resi, de 500 a 5000 threads nos pacotes
Funciona com o checker que você já usa
Resi por login e senha na string, pacotes por IP; A-Parser, Key Collector e Rank Tracker aceitam HTTP e SOCKS5
Uma página de resultados pesa pouco, então um gigabyte cobre milhares de consultas. O preço por GB cai com o tamanho do pedido.
| Tamanho do pedido | Resi Core | Resi Prime |
|---|---|---|
| 1 GB+ | $0.85 | $2.29 |
| 10 GB+economize 7% | $0.79 | $2.09 |
| 50 GB+ | $0.72 | $1.95 |
| 100 GB+ | $0.65 | $1.75 |
| 500 GB+ | $0.57 | $1.55 |
| 1000 GB+ | $0.49 | $1.39 |
Preços em dólares americanos por 1 GB. Você compra gigabytes inteiros, a partir de um.
Pool
Você economiza 7% ($1.50) em relação ao preço de 1 GB+
Adicione 25 GB e cada gigabyte cai para $0.72
Comprar esta quantidadeVocê pode usar os gigabytes por 3 meses a partir da compra; o que sobrar depois disso é baixado.
Acompanhe o Google.de pela Europa, o Yandex pela CEI e o Baidu pela China. O World MIX cobre o resto e tem os maiores pools.
Pegue a exportação CSV e fique com as linhas cuja coluna de país bate com o mercado acompanhado; o gerador pronto grava um arquivo ip:port por país.
Rank checkers aceitam um arquivo de proxies ou uma URL. Defina a atualização a cada 10 minutos e a lista se mantém em dia sozinha.
Defina DOMAIN e COUNTRY e coloque suas palavras-chave em keywords.txt. O script consulta o buscador por um proxy desse país e grava a posição do seu domínio num CSV. Use um pool limpo do verificador de proxies.
#!/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()
Cole uma linha Resi do seu painel, defina DOMAIN e coloque as palavras-chave em keywords.txt. O script abre os resultados num Chromium de verdade pelo proxy, espera o bloco de IA terminar de carregar e grava no CSV se o bloco aparece, quais domínios ele cita e se o seu está entre eles. Ele fecha sozinho o banner de cookies da UE e marca captcha ou erro de proxy numa linha separada. O Google muda o markup, então o título do bloco fica em 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()
No A-Parser e no Key Collector, cole a lista ip:port no campo de proxies e defina o intervalo de checagem para que uma palavra-chave passe por um endereço no máximo uma vez por dia. O Rank Tracker e programas parecidos leem um arquivo de proxies; aponte para a lista que o gerador grava por país.
As posições dependem de onde vem a consulta, então mantenha uma lista por mercado: uma instância do tracker por país, cada uma só com endereços daquele país.
O script acima consulta o buscador por um proxy do país e registra a colocação do seu domínio. Envie os parâmetros de idioma e região do buscador junto com o proxy: o endereço define o país e os parâmetros, a cidade.
Confira o pool antes de cada rodada no verificador de proxies; para um teste manual leve, a lista de proxies grátis serve. Uma introdução às SERPs regionais vai ficar nos artigos.
Cada vez mais o Google coloca um bloco de IA acima dos resultados comuns: uma resposta curta com links para fontes. Parte dos cliques vai para lá, então você precisa saber se o seu site entrou nas fontes e quais consultas não mostram o bloco. O bloco é montado pela localização do usuário: para uma mesma consulta, Berlim e Munique podem ver fontes diferentes.
Um scraper de resultados comum nunca vê esse bloco: o Google o desenha com JavaScript depois que a página carrega. Você precisa de um navegador de verdade, como o Chromium com Playwright, e de um IP residencial do país certo. Endereços de lista costumam cair em captcha nesses resultados, por isso aqui quem trabalha são o Resi Core e o Resi Prime.
Para acompanhar por país basta o Resi Core com o código do país no login. Quando o cliente se importa com uma cidade, escolha o Resi Prime com a cidade na string e uma sessão fixa por lote de consultas: assim o lote inteiro sai de um endereço daquela cidade.
Rode a lista de palavras-chave uma vez por dia ou uma vez por semana: o bloco de IA muda mais devagar que as posições comuns. Para cada consulta anote a data, o país ou a cidade, se o bloco aparece, quais domínios ele cita e se o seu está entre eles. Depois de um mês dá para ver quais páginas a IA usa na resposta e quais saíram.
O segundo script acima grava exatamente esses campos em CSV. O primeiro script acompanha as posições comuns no mesmo país, então os dois relatórios batem por consulta.

Acompanhe os resultados por país pelo Resi Core e por cidade pelo Resi Prime, e rode listas grandes de palavras-chave todo dia num pacote ilimitado por menos.
Resultados por paísMelhor escolha
Um IP residencial do país certo a cada requisição. Uma página de resultados pesa pouco, então um gigabyte cobre milhares de consultas.
a partir de $0.49 por GB1 GB por $0.85
Resultados por cidade
Cidade e região na string de conexão dão os resultados que um usuário daquela cidade vê.
a partir de $1.39 por GB1 GB por $2.29
Listas grandes de palavras-chave
Dezenas de milhares de consultas por dia sem medidor de tráfego. O país do mercado você escolhe pela coluna do CSV exportado.
$378 por mêsou $2.10 por hora
Pegue 1 GB de Resi Core, defina o país na string e rode o checker em endereços vivos.