← 返回博客

为什么爬虫显示网站的错误区域:Accept-Language、货币和地理Cookie

为什么爬虫下载的页面版本与真实用户看到的不同,以及如何通过头部信息、cookie 和正确选择代理来修复这个问题。

📅2026年10月22日

解析器启动,代码没有崩溃,数据也在返回——但价格是美元而不是卢布,文本是英文的, 而且商品与来自俄罗斯的活跃用户看到的商品不同。这是解析中最常见和令人沮丧的问题之一: 从技术上讲,一切正常,但内容“不是那个”。我们来分析一下这是为什么,以及如何构建 请求,以获取您所需的页面版本。

症状:如何判断解析器看到的不是正确版本

在修复问题之前,正确诊断它是很重要的。有三种典型情况导致解析器获取的数据与普通 浏览器用户看到的不同:

  • 内容语言不匹配——您期望看到俄文文本,但返回的是英文或 乌克兰文的页面。
  • 货币和价格不同——网站显示的价格是美元或欧元,而在来自俄罗斯的 浏览器中您看到的是卢布,或者数字根本不同(区域定价)。
  • 商品/内容目录不同——商品的可用性、促销、整个展示窗都依赖于 网站“看到”的区域。

原因几乎总是三种之一(或它们的组合):Accept-Language头部、 缺失或错误的cookie,或者请求的IP地址的地理位置。我们将逐一分析每个原因。

Accept-Language:服务器如何选择响应语言

浏览器在每个请求中发送Accept-Language头部, 其中列出了用户的首选语言及其权重(q值)。以下是Chrome在俄语区域发送的实际示例:

Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7

解析库(requests、httpx、scrapy)默认情况下要么根本不发送此头部,要么发送类似 */*的内容。 在这种情况下,服务器要么返回默认语言(通常是英语),要么根据IP确定语言—— 这时地理部分就发挥作用,下面将对此进行说明。

重要的细节:许多网站使用“Accept-Language + IP地理位置”的组合,而不是单独使用其中之一。 也就是说,即使您发送了正确的语言头部,但请求来自其他国家的IP,网站仍然可能 将您切换到该区域的英语或本地版本。

货币和区域:网站如何获取价格

货币几乎从不直接通过Accept-Language头部确定。通常使用以下三种机制之一(或它们的组合):

  1. GeoIP数据库——服务器查看IP来自哪个国家,并在首次访问时自动 插入相应的货币和区域。
  2. 之前选择的区域的cookie——如果用户曾经手动选择过国家和货币, 网站会将其保存在cookie中,并不再检查IP。
  3. URL参数或子域——一些平台使用显式标记,例如 ?country=ru或 ru.example.com。

在实践中,如果您在解析网上商店时看到价格是美元而不是卢布,80%的情况下问题不在 头部,而在于请求的IP地址。网站只是“看到了”非俄罗斯的IP,并插入了默认的 国际展示。

一旦网站确定了您的区域(通过IP或在“选择您的城市”横幅上手动选择),它会将此决策 保存到cookie中——通常命名为 region, geo_city, currency或 locale。 之后,所有带有此cookie的请求都将根据保存的区域进行处理——即使IP突然改变。

这为解析器创造了一个陷阱:如果您一次获得了“错误”的版本并保存了会话cookie, 所有后续请求将重复同样的错误,即使您修复了头部或代理。因此,在诊断时,请始终 检查使用干净的会话进行解析——没有来自先前运行的保存的cookie。

同样机制的另一面是有用的:如果您知道所需cookie的名称及其在目标区域的正确值 (例如,在所需位置的浏览器DevTools中查看),可以在请求中强制设置此值,而不更改IP。 这适用于仅通过cookie标志确定区域的网站,但如果服务器在每个请求中重新检查IP与 GeoIP数据库的匹配,则无效。

IP地址和代理在确定区域中的作用

GeoIP定位是网站了解请求实际来源的最可靠方法,因为头部和cookie可以伪造,而IP地址 是无法伪造的(只能替换为另一个真实的)。因此,为了稳定地获取“正确”的区域版本 页面,仅有HTTP头部是不够的——需要一个确实属于所需国家的IP。

在IP地址类型之间存在显著差异:

  • 数据中心IP——GeoIP数据库通常能正确识别其国家,但许多大型 网站(尤其是市场和防止机器人服务)将数据中心的IP范围标记为可疑,并可能显示 削减或默认版本的内容,而不考虑地理位置。
  • 住宅IP——属于真实的提供商和物理地址,因此GeoIP更准确地确定区域, 网站将请求视为来自该国家/城市的普通用户。
  • 移动IP——绑定到特定国家的移动运营商,这对处理特定国家的 移动和桌面流量的网站和应用特别重要。

对于像Wildberries、Ozon或Avito等特定城市的价格监控任务,最适合使用 住宅代理——它们提供 与真实区域绑定的IP,GeoIP数据库正确识别国家和城市,而不会替换为默认的国际展示。

实践:在Python中构建正确的请求

我们将构建一个同时解决所有三个问题的请求:发送正确的Accept-Language, 使用带有所需cookie的干净会话,并通过所需区域的IP进行请求。

import requests

proxies = {
    "http": "http://user:[email protected]:8080",
    "https": "http://user:[email protected]:8080",
}

headers = {
    "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/124.0.0.0 Safari/537.36",
}

cookies = {
    "region": "ru",
    "currency": "RUB",
}

session = requests.Session()
response = session.get(
    "https://example.com/catalog",
    headers=headers,
    cookies=cookies,
    proxies=proxies,
    timeout=15,
)

print(response.status_code)
print(response.text[:500])

这段代码中的几个重要点:

  • 使用requests.Session(), 而不是单个requests.get(), 以便在需要时服务器可以设置额外的cookie,并在同一解析会话的请求之间保持它们。
  • cookie的值region 和currency是条件的, 它们的真实名称和值需要在目标网站的DevTools(应用程序选项卡→cookie)中查看。
  • 代理必须确实位于所需国家——否则即使头部和cookie正确,服务器在重新确定地理位置时也可能会覆盖它们。

JS网站:Playwright和头部/cookie管理

如果网站通过JavaScript渲染内容(价格在页面加载后通过单独请求加载), 简单的requests请求是不够的——需要无头浏览器。在Playwright中,区域、语言和代理 在浏览器上下文级别设置:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    context = browser.new_context(
        locale="ru-RU",
        timezone_id="Europe/Moscow",
        proxy={
            "server": "http://gate.proxycove.com:8080",
            "username": "user",
            "password": "pass",
        },
    )
    context.add_cookies([
        {"name": "region", "value": "ru", "domain": "example.com", "path": "/"},
        {"name": "currency", "value": "RUB", "domain": "example.com", "path": "/"},
    ])

    page = context.new_page()
    page.goto("https://example.com/catalog")
    page.wait_for_selector(".price")
    print(page.content()[:500])

    browser.close()

请注意timezone_id参数—— 许多网站还会将浏览器的时区与区域预期的时区进行核对,时区不一致(例如,IP来自俄罗斯, 而浏览器的时区是美国的)本身可能会被反机器人系统视为可疑请求,即使语言和货币在形式上是正确的。

常见错误和启动前的检查清单

在将解析器投入生产之前,请检查一个简短的检查清单——这可以节省几个小时的调试时间:

  • ✅ Accept-Language头部已设置并符合预期区域。
  • ✅ 会话是干净的——cookie没有从先前失败的请求中继承。
  • ✅ 代理的IP物理上位于所需国家(在解析之前通过任何geo-IP检查器进行检查)。
  • ✅ User-Agent符合真实浏览器,并且不包含无头模式的迹象。
  • ✅ 浏览器的时区和区域(对于Playwright/Selenium)与IP所在国家一致。
  • ✅ 如果网站使用手动选择区域的横幅——该选择的cookie手动传递。

另外要提到的是代理的轮换:如果您在每个请求中更改IP,而会话cookie保持不变, 网站可能会看到“区域A的cookie,但区域B的IP”的不一致,并重置会话。对于价格监控任务, 最好将一个IP固定在特定区域的整个解析会话中,而不是在数据收集过程中轮换它。

选择哪种类型的代理来完成任务

代理类型的选择直接影响网站确定您的区域的准确性,并且不会怀疑自动化。以下是 针对典型的区域版本网站解析任务的比较:

代理类型 地理定位准确性 何时使用
数据中心代理 中等,国家正确,但IP可能被标记为“非住宅” 解析没有严格反机器人保护的网站,高速和大量请求
住宅代理 高,甚至到城市级别 监控市场的价格、区域内容、绕过GeoIP检查
移动代理 高,加上移动运营商的标记 特定国家的移动流量和桌面流量处理不同的网站和应用

如果任务是监控来自不同城市的市场目录和价格,住宅代理通常会提供最可预测的结果: GeoIP数据库看到真实的住宅地址,而不是某些网站用不同逻辑处理的数据中心范围。

结论

“解析器看到的不是页面的正确版本”问题几乎总是由三个因素组成:Accept-Language头部, 它确定首选的响应语言;cookie,它们记住之前选择的区域和货币;以及IP地址的地理位置, 服务器在首次访问时根据该地址确定请求的国家。为了获取活跃用户看到的确切网站版本, 需要同时同步这三个参数,而不是单独修复它们。

如果您定期解析区域版本的网站,监控市场上竞争对手的价格或从不同国家收集数据, 建议从选择合适的IP开始——其他设置(头部、cookie、时区)围绕它进行构建。为了准确 进入所需区域,建议尝试住宅代理, 它们提供可预测的地理定位,并将获取默认国际版本网站而不是本地版本的风险降至最低。