You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于tiler.php的Web地图瓦片爬取问题求助

解决Thinkbroadband宽带地图瓦片爬取问题

问题根源

直接访问tiler.php返回空白是因为服务器验证了请求来源(Referer)和用户代理(User-Agent),仅允许来自原地图页面的合法浏览器请求。

步骤1:分析合法瓦片请求参数

通过浏览器开发者工具(Network标签)查看瓦片加载请求,可发现合法请求包含:

  • 核心URL:https://labs.thinkbroadband.com/local/tiler.php?z={zoom}&x={x}&y={y}&provider={provider}(比如provider为virgin)
  • 必要请求头:Referer需指向原地图页面,User-Agent需模拟真实浏览器

步骤2:Python单瓦片爬取实现

使用requests库构造合法请求,获取并保存瓦片:

import requests

def fetch_tile(z, x, y, provider="virgin"):
    tile_url = f"https://labs.thinkbroadband.com/local/tiler.php?z={z}&x={x}&y={y}&provider={provider}"
    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://labs.thinkbroadband.com/local/broadband-map"
    }
    
    resp = requests.get(tile_url, headers=headers)
    if resp.status_code == 200 and resp.headers["Content-Type"] == "image/png":
        with open(f"tile_z{z}_x{x}_y{y}.png", "wb") as f:
            f.write(resp.content)
        return True
    print(f"Failed to fetch tile: z={z}, x={x}, y={y}")
    return False

# 测试获取单张瓦片
fetch_tile(6, 32, 20)

步骤3:批量爬取指定范围瓦片

遍历目标瓦片的x、y范围,批量获取:

import time

def batch_fetch(z, x_start, x_end, y_start, y_end, provider="virgin", delay=1):
    for x in range(x_start, x_end + 1):
        for y in range(y_start, y_end + 1):
            fetch_tile(z, x, y, provider)
            time.sleep(delay)  # 加延迟避免被封禁

# 示例:爬取zoom=6,x从30到35,y从18到23的瓦片
batch_fetch(6, 30, 35, 18, 23)

步骤4:瓦片合并与地理配准

用PIL库合并瓦片,再通过Web Mercator坐标系(EPSG:3857)进行地理配准:

from PIL import Image
import os

def merge_tiles(z, x_start, x_end, y_start, y_end, output="merged_map.png"):
    tile_size = 256
    map_width = (x_end - x_start + 1) * tile_size
    map_height = (y_end - y_start + 1) * tile_size
    
    merged_map = Image.new("RGBA", (map_width, map_height))
    
    for x in range(x_start, x_end + 1):
        for y in range(y_start, y_end + 1):
            tile_path = f"tile_z{z}_x{x}_y{y}.png"
            if os.path.exists(tile_path):
                tile = Image.open(tile_path)
                x_offset = (x - x_start) * tile_size
                y_offset = (y - y_start) * tile_size
                merged_map.paste(tile, (x_offset, y_offset))
    
    merged_map.save(output)
    print(f"Merged map saved to {output}")

# 合并批量爬取的瓦片
merge_tiles(6, 30, 35, 18, 23)

关键注意事项

  • 延迟请求:添加time.sleep()避免触发服务器反爬机制
  • 请求头更新:若爬取失败,检查并更新User-Agent为当前主流浏览器标识
  • Cookie验证:若后续出现403错误,可先请求原地图页面获取Cookie,再带入瓦片请求

内容的提问来源于stack exchange,提问作者AW_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:50:29