如何自动获取Rentfaster接口POST请求所需的l与area参数值?
如何自动获取Rentfaster.ca API所需的
l和area参数 问题背景
我编写了爬虫抓取Rentfaster.ca的房源数据,目前可通过手动从开发者工具复制l和area参数,调用/api/map.json接口获取房源总数或城市房源数据,但不清楚这两个参数的生成逻辑,也不知道如何针对不同城市(如卡尔加里)自动获取这两个参数。
手动调用的示例代码如下:
获取总房源数
import requests url = 'https://www.rentfaster.ca/api/map.json' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', } params = { 'l': '4,54.9773,-112.766', 'area': '59.68965038087162,-91.935921875,49.63882324278784,-133.596078125', 'exclude': '' } res = requests.post(url, data=params, headers=headers) print(res.json()['total'])
城市房源查询(卡尔加里示例)
import requests url = 'https://www.rentfaster.ca/api/map.json' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', } params = { 'l': '13,51.0452,-114.0764', 'area': '51.058053440451424,-114.0356853316207,51.03236736163589,-114.11705282429648', 'e': 'zoom_changed', 'exclude': '' } res = requests.post(url, data=params, headers=headers) print(res.json())
解决方法
先明确参数含义
l参数:格式为[区域ID],[中心纬度],[中心经度],其中区域ID是Rentfaster内部对城市/地区的唯一标识,经纬度是该区域的地理中心点坐标。area参数:格式为[东北纬度],[东北经度],[西南纬度],[西南经度],是一个地理边界框,用来限定API返回的房源范围。
方法1:爬取城市页面提取参数
Rentfaster的城市房源页面中已经包含了这两个参数,可直接从页面源码或URL中提取:
- 提取
l参数:城市房源页面的URL中已携带l参数,直接解析URL的query参数即可获取。 - 提取
area参数:打开城市页面源码,搜索area关键词,通常会在页面初始化的JS代码(如全局变量、配置片段)中找到该参数的定义。
示例代码:
import requests from bs4 import BeautifulSoup from urllib.parse import urlparse, parse_qs import re def get_city_params(city_url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', } # 获取页面内容 response = requests.get(city_url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 提取l参数 parsed_url = urlparse(city_url) l_param = parse_qs(parsed_url.query).get('l', [None])[0] # 提取area参数 area_param = None for script in soup.find_all('script'): if script.string and 'area:' in script.string: match = re.search(r'area:\s*"([^"]+)"', script.string) if match: area_param = match.group(1) break return l_param, area_param # 调用示例:卡尔加里的房源页面 calgary_url = 'https://www.rentfaster.ca/ab/calgary/rentals/' l, area = get_city_params(calgary_url) print(f'l参数: {l}') print(f'area参数: {area}')
方法2:结合区域ID映射与地理编码API
如果需要批量处理多个城市,可按以下步骤操作:
- 收集区域ID映射:手动抓取几个城市的页面,记录城市名对应的
l参数中的区域ID(如维多利亚对应4,卡尔加里对应13),建立映射字典。 - 获取边界框:使用免费地理编码API(如OpenStreetMap Nominatim)输入城市名,获取其地理边界框,再转换为Rentfaster所需的
area参数格式。
示例代码:
import requests # 预定义区域ID映射(可手动扩展) city_area_id_map = { 'Victoria, BC': '4', 'Calgary, AB': '13' } def get_city_bounding_box(city_name): url = f'https://nominatim.openstreetmap.org/search?q={city_name}&format=json&polygon_geojson=1' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'} response = requests.get(url, headers=headers) data = response.json() if not data: return None # 转换为Rentfaster需要的格式:东北纬度,东北经度,西南纬度,西南经度 bbox = data[0]['boundingbox'] return f"{bbox[1]},{bbox[3]},{bbox[0]},{bbox[2]}" def get_city_center(city_name): url = f'https://nominatim.openstreetmap.org/search?q={city_name}&format=json' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'} response = requests.get(url, headers=headers) data = response.json() if data: return data[0]['lat'], data[0]['lon'] return None, None def get_params_for_city(city_name): area_id = city_area_id_map.get(city_name) if not area_id: return None, None center_lat, center_lon = get_city_center(city_name) l_param = f"{area_id},{center_lat},{center_lon}" area_param = get_city_bounding_box(city_name) return l_param, area_param # 调用示例 l, area = get_params_for_city('Calgary, AB') print(f'l参数: {l}') print(f'area参数: {area}')
注意事项
- 保持请求头一致性,避免频繁请求触发Rentfaster的反爬机制导致IP被封禁。
- 方法1的可靠性更高,直接从目标站点获取参数,不会出现地理编码API返回边界框与站点不一致的问题。
内容的提问来源于stack exchange,提问作者MITHU
相关产品推荐
相关产品推荐

