Appearance
多账号运营怎么防关联?用 IP 归属地自查账号关联风险(Python 实现)
做了三年跨境电商的运营老赵,手上有 6 个店铺账号,最近一个月被封了 2 个,申诉邮件里都提到一句「存在关联风险」。他不死心,找了一圈论坛,结论基本一致:IP 是平台判定关联最硬的一张牌。同一个出口 IP 登录多个账号,哪怕你换了电脑、换了浏览器,账号照样可能被绑在一起。这篇文章就写怎么用 IP 归属地接口,把自己手上账号的登录记录跑一遍自查,提前把风险揪出来。
一、账号为什么会「被关联」
平台判定账号关联,靠的是多维信号叠加:设备指纹(浏览器、显卡、时区)、支付方式、收货地址、行为轨迹,以及——IP。IP 是里面最直白的一个:两个账号在相近的时间从同一个公网 IP 登录,很难解释成巧合。
但普通人容易把这事理解反。关联不是说「同 IP 必然封号」,而是「同 IP + 其他特征叠加」才触发风控。所以自查要做的不是看单条记录,而是把账号、IP、城市、运营商、登录时间摊开,找「异常聚集」:
- 一个 IP 下挂着几个账号(同出口)
- 多个账号的归属地在同一城市、同一运营商
- 某个账号的登录地城市频繁快速漂移(一分钟前北京、一分钟后广州,脚本特征)
这三类信号,靠 IP 归属地数据就能扫出来大半。
二、自查思路:给登录记录打上属地标签
把手上的账号登录记录整理成一张表:账号、登录 IP、登录时间。然后对每个 IP 调一次归属地接口,拿到省份、城市、运营商,把标签并回去,再按维度聚合统计。
这里有个现实约束:不少平台的登录日志只存了 IP,没存城市。IP 归属地接口就是来补这块的。免费额度一天几百次完全够个人自查用——IP9 的免费版是 60 次/分钟/IP,查完几十个账号绰绰有余(https://ip9.com.cn/get?ip=<ip>,一次返回国家/省/市/运营商/经纬度)。接口不支持批量,循环调用时自己加个限速就行。
三、Python 实现
核心逻辑就三步:读记录 → 查归属地(带缓存,同一 IP 只查一次)→ 聚合统计。下面这段可以直接跑:
python
import csv
import json
import time
import urllib.request
from collections import defaultdict, Counter
API = "https://ip9.com.cn/get?ip={ip}"
CACHE = {} # ip -> 归属地信息,同一 IP 只查一次
LAST_REQ = 0 # 简单限速:免费版 60 次/分钟,这里控制到 1 秒 1 次
MIN_GAP = 1.0
def lookup(ip):
"""查询 IP 归属地,失败时返回 None。"""
global LAST_REQ
if ip in CACHE:
return CACHE[ip]
now = time.time()
if now - LAST_REQ < MIN_GAP:
time.sleep(MIN_GAP - (now - LAST_REQ))
LAST_REQ = time.time()
try:
req = urllib.request.Request(API.format(ip=ip), headers={"User-Agent": "ip9-self-check/1.0"})
with urllib.request.urlopen(req, timeout=5) as resp:
data = json.loads(resp.read().decode("utf-8"))
if data.get("ret") != 200:
return None
d = data["data"]
info = {"prov": d.get("prov", ""), "city": d.get("city", ""), "isp": d.get("isp", "")}
CACHE[ip] = info
return info
except Exception:
return None
def load_records(path):
"""读取登录记录:account, ip, time 三列。"""
with open(path, encoding="utf-8") as f:
return list(csv.DictReader(f))
def analyze(records):
ip_accounts = defaultdict(set) # ip -> {账号}
acct_cities = defaultdict(set) # 账号 -> {城市}
acct_isps = defaultdict(set)
for r in records:
ip = r["ip"].strip()
info = lookup(ip)
acct = r["account"].strip()
if not info:
continue
ip_accounts[ip].add(acct)
acct_cities[acct].add(f"{info['prov']}-{info['city']}")
acct_isps[acct].add(info["isp"])
return ip_accounts, acct_cities, acct_isps
def report(ip_accounts, acct_cities, acct_isps):
print("== 高亮:一个 IP 下挂了多个账号 ==")
for ip, accts in sorted(ip_accounts.items(), key=lambda x: -len(x[1])):
if len(accts) >= 2:
print(f" {ip}: {len(accts)} 个账号 -> {sorted(accts)}")
print("== 高亮:账号登录地出现多个城市 ==")
for acct, cities in acct_cities.items():
if len(cities) > 1:
print(f" {acct}: {sorted(cities)}")
print("== 账号数统计 ==")
print(" 账号总数:", len(acct_cities))
ip_cnt = Counter(len(v) for v in ip_accounts.values())
print(" IP 分布:", dict(sorted(ip_cnt.items())))
if __name__ == "__main__":
records = load_records("login_records.csv")
ip_accounts, acct_cities, acct_isps = analyze(records)
report(ip_accounts, acct_cities, acct_isps)login_records.csv 长这样(表头三列即可):
csv
account,ip,time
shop_a,114.114.114.114,2026-09-20 10:00:00
shop_b,114.114.114.114,2026-09-20 10:05:00
shop_a,123.125.115.110,2026-09-21 09:00:00跑完它会直接告诉你:哪个 IP 挂着多个账号、哪个账号在多个城市登录过。这两类就是平台风控最喜欢的切入点。
四、落地注意事项
- 同 IP 不等于实锤。公司/校园网是共享出口,几十号人同一个公网 IP 很正常。自查报告里出现「同 IP 多账号」,先看运营商是不是住宅宽带、时间是不是接近,别一上来就下结论。
- IP 只是其中一环。设备和行为信号平台同样在看,IP 自查干净不代表绝对安全;反过来,独享代理换 IP 也盖不住指纹雷同。要隔离就全维度隔离,只换 IP 是自欺欺人。
- 限速和缓存是标配。免费接口有 60 次/分钟的限制,脚本里已经做了 1 秒 1 次限速和同 IP 缓存。数据量大就拉长间隔,别硬刚限流。
- 合规边界:这套逻辑用来自查自己的账号、或者平台做风控是正当的;拿去批量注册、搞黑产多开,属于另一回事,不在讨论范围。
总结
多账号防关联,第一步永远是「知道自己账号的 IP 画像长什么样」。用 IP9 免费接口(https://ip9.com.cn/get?ip=xxx,无需注册,直接 get 调用)给登录记录打属地标签,几十行 Python 就能把「同 IP 多账号」「多地漂移」两类高风险信号扫出来。想更细一点,免费版返回的 isp 运营商字段还能帮你区分住宅带宽和机房 IP。定期跑一遍,比封号之后再申诉省心得多。官网:https://www.ip9.com.cn 。