首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >多城市租房采集:地域定向代理实测与防漂移落地代码

多城市租房采集:地域定向代理实测与防漂移落地代码

原创
作者头像
永不掉线的小白
发布于 2026-09-29 15:52:55
发布于 2026-09-29 15:52:55
460
举报

做租房爬虫,本地跑没问题,一上多城市就废。我前段时间抓上海、杭州、南京、成都的租金行情,用混拨代理采上海浦东,IP,一会儿跳北京、一会儿跳深圳,房源城市都对不上;跑半小时开始超时;接口还返回 200,但租金、户型、看房时间这些字段是空的。后面排查发现,不是代码问题,也不是 sleep 写得不对,核心是代理 IP 的地域不对。房产平台会看请求 IP 的归属地和房源城市是否一致,跨城请求很容易被判异常。

前提:只采公开房源,遵守平台规则和 robots,别碰登录后数据、隐私数据,也别高频打。

为什么普通代理在租房采集里不好用

通用混拨、免费代理,基本不适合房产采集:

- 平台会校验 IP 归属地。你采上海房源,IP 在杭州,可能直接 403、验证码,或者返回空数据。

- 混拨代理全国随机跳,固定不了城市。多城采集时,脏数据会非常多。

- 低价代理存活差,断线重连多。重连多了,反而更容易触发平台频控。

所以别一上来就改 UA、加 sleep。先看 IP 城市对不对。

我这边 8 小时实测结果

测试场景:上海、杭州、南京、成都,多城市租房房源采集,包括基础信息、租金、配套、发布时间。

测试对象:通用混拨动态代理、普通城市定向代理、住宅级稳定定向代理。

测试时长:连续 8 小时。

看这几个指标:地域准确率、连接成功率、延迟波动、封禁报错率、有效数据完整率。

通用混拨代理

目标城市匹配率只有 35%,大量请求跨城。

8 小时里断线超时频繁,整体连接成功率 68%。

跑 2 小时开始弹验证码,3 小时后 403 报错率超过 40%。

核心字段缺失严重,有效可用数据不到 50%。

这个只能临时手动看看,不适合正式采集。

普通城市定向代理

地域问题好一些,精准度能到 92%,基础地域风控能过。

但节点存活短,IP 轮换频繁,延迟 80ms 到 400ms 乱跳,会话偶尔断。

整体连接成功率 85%。

连续跑 4 小时后开始零星验证码,封禁率 8%,有效数据率 82%。

适合短时、单城市、小批量。长时间多城批量,容易掉链子。

住宅级稳定定向代理

真实住宅 IP,归属地干净,实测表现最好:

地域精准度 100%,没出现跨城错乱;

8 小时连续跑,连接成功率 98% 以上,几乎不断线;

延迟稳定在 90-150ms,没有突发卡顿;

全程没有 403、没有强制验证码,封禁率接近 0;

房源核心字段完整,有效数据率 100%,不用反复补采。

选代理的结论

1. 地域匹配优先,速度往后放。

租房采集不是比谁请求快,IP 城市错了,采回来也是废数据,还会把 IP 拉黑。

2. 看长时间稳定性,别只看瞬时低延迟。

有些代理刚连上很快,跑一小时就开始轮换、断线、封禁。批量采集要看 8 小时以上的表现。

3. 免费和低价混拨别用。

这类 IP 很多被爬虫滥用过,早进平台风控名单了。省的是代理费,赔的是漏采、重跑、清洗时间。

可直接照做的落地规则

1. 按城市隔离 IP 池。

上海任务只用上海 IP,杭州任务只用杭州 IP。一个线程固定一个城市,禁止跨城市混用节点。

2. 关闭高频 IP 轮换。

用粘性会话,别每个请求都换 IP。比如 10-30 分钟换一次,或者跑几百个请求再换。模拟真人长时间浏览。

3. 校验地域别太频繁。

换 IP 后校验一次,之后每 20-50 个请求抽检。遇到 403、验证码、空数据,立刻重新校验。免费 IP 查询接口有限速,别每次请求都查。

4. 请求侧配合做。

随机间隔 0.8-2 秒,带正常 UA、Referer,复用 cookie。单城并发别太高,先 2-5 个跑稳,再慢慢加。

5. 返回 200 不代表成功。

租金、户型、发布时间这些字段,至少校验两个。缺字段就当失败,重试或换 IP。

6. 按城市看监控。

记录每个城市的成功率、403 率、验证码率、空字段率。某个城市掉到 90% 以下,就降速、换池、换节点。

可复用代码

注意:`switch_proxy()` 必须接你代理商的换 IP API,否则重试还是同一个 IP。

代码语言:txt
复制
import requests
import time
import random

PROXY_URL = "http://用户名:密码@代理host:端口"
TARGET_CITY = "上海"

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/120.0.0.0 Safari/537.36",
    "Referer": "https://fang.com/"
}

PROXIES = {
    "http": PROXY_URL,
    "https": PROXY_URL
}

session = requests.Session()
session.headers.update(HEADERS)

_last_check_ts = 0
CHECK_EVERY_SECONDS = 60  # 或按请求数,比如每30个请求查一次
_req_count = 0


def get_ip_city():
    """查当前代理IP归属城市。ip-api免费版有限速,别查太勤。"""
    try:
        r = session.get(
            "http://ip-api.com/json/?lang=zh-CN",
            proxies=PROXIES,
            timeout=5
        )
        data = r.json()
        if data.get("status") != "success":
            return False, data.get("message", "查询失败")
        city = data.get("city") or ""
        return TARGET_CITY in city, city
    except Exception as e:
        return False, str(e)


def switch_proxy():
    """
    这里必须接代理商的换IP接口,或者用支持粘性会话的代理参数。
    不换IP的话,重试大概率还是同一个节点。
    """
    # 示例思路:
    # new_ip = requests.get("代理商的提取API").text
    # 更新全局 PROXIES
    pass


def need_check(force=False):
    global _last_check_ts, _req_count
    now = time.time()

    if force or now - _last_check_ts > CHECK_EVERY_SECONDS:
        _last_check_ts = now
        _req_count = 0
        return True

    _req_count += 1
    return False


def is_valid_rent_html(html):
    """
    这里别只判断200。按你页面结构加:
    租金、户型、发布时间至少两个存在。
    """
    if not html:
        return False
    # 示例:return "租金" in html and "户型" in html
    return True


def fetch_rent(url, max_retry=3):
    for attempt in range(max_retry):
        if need_check(force=(attempt == 0)):
            ok, city = get_ip_city()
            if not ok:
                print(f"IP地域不对,当前:{city},目标:{TARGET_CITY},准备换IP")
                switch_proxy()
                time.sleep(random.uniform(1, 2))
                continue

        try:
            time.sleep(random.uniform(0.8, 2.0))
            resp = session.get(url, proxies=PROXIES, timeout=8)

            if resp.status_code in (403, 429, 502):
                print(f"触发风控或限流:{resp.status_code},换IP重试")
                switch_proxy()
                time.sleep(random.uniform(2, 4))
                continue

            resp.raise_for_status()

            if not is_valid_rent_html(resp.text):
                print("页面字段不完整,当失败处理")
                switch_proxy()
                time.sleep(random.uniform(1, 3))
                continue

            return resp.text

        except Exception as e:
            print(f"请求异常:{e},重试")
            switch_proxy()
            time.sleep(random.uniform(1, 3))

    return None


if __name__ == "__main__":
    rent_url = "目标租房房源链接"
    html = fetch_rent(rent_url)

    if html:
        print("采集成功,可以解析户型、租金、发布时间等字段")
    else:
        print("采集失败,检查代理城市、稳定性或换节点")

最后一句:租房采集先解决 IP 城市,再谈稳定性和速度。IP 地域不对,代码写得再漂亮也白搭。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 为什么普通代理在租房采集里不好用
  • 我这边 8 小时实测结果
    • 通用混拨代理
    • 普通城市定向代理
    • 住宅级稳定定向代理
  • 选代理的结论
    • 1. 地域匹配优先,速度往后放。
    • 2. 看长时间稳定性,别只看瞬时低延迟。
    • 3. 免费和低价混拨别用。
  • 可直接照做的落地规则
    • 1. 按城市隔离 IP 池。
    • 2. 关闭高频 IP 轮换。
    • 3. 校验地域别太频繁。
    • 4. 请求侧配合做。
    • 5. 返回 200 不代表成功。
    • 6. 按城市看监控。
  • 可复用代码
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档