基于API的城市驾车距离筛选教程

聖光之護
发布: 2025-10-18 12:14:22
原创
554人浏览过

基于API的城市驾车距离筛选教程

本文将详细介绍如何高效地根据驾车距离筛选城市列表。文章将阐述为何直接进行网页抓取存在局限性,并推荐转而利用专业的距离计算api(如`distance.to`)作为更可靠、高效的解决方案。我们将通过实际代码示例,指导读者实现从指定“主位置”筛选出75公里内城市的完整流程,并强调api使用的优势、注意事项及最佳实践。

在现代应用开发中,根据地理位置或距离筛选数据是一项常见需求。例如,您可能需要从一个城市列表中找出距离特定“主位置”在指定范围内的所有城市。这在物流、本地服务推荐或地理信息系统中都非常有用。

直接网页抓取的局限性与挑战

最初,面对这样的需求,许多开发者可能会考虑直接从提供距离查询服务的网站(如luftlinie.org)抓取数据。这种方法通常涉及以下步骤:

  1. 构建带有城市名称的查询URL。
  2. 发送HTTP请求获取网页内容。
  3. 解析HTML页面,提取包含距离信息的特定元素(例如,一个带有特定ID或class的<span>标签)。
  4. 将提取到的距离数据进行比较和筛选。

然而,这种直接的网页抓取(Web Scraping)方法存在诸多问题:

  • 跨域资源共享(CORS)问题: 浏览器出于安全考虑,会阻止网页脚本向不同源的服务器发起请求。这意味着您在自己的网站上运行的JavaScript代码,很难直接抓取另一个网站的内容。
  • HTML结构不稳定: 目标网站的HTML结构可能随时改变,导致您的解析代码失效,需要频繁维护。
  • 效率低下: 抓取整个网页并解析HTML通常比直接获取结构化数据更耗时、耗资源。
  • 法律与道德风险: 未经许可的网页抓取可能违反网站的服务条款,甚至涉及法律风险。
  • 缺乏API密钥管理: 无法有效控制请求频率,容易被目标网站封禁IP。

以下是一个尝试直接抓取luftlinie.org的失败示例,它很可能因为CORS问题而无法正常工作:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// 这种尝试通常会遇到CORS错误,因为浏览器阻止了跨域请求
$.get('https://www.luftlinie.org/Hameln,Niedersachsen,DEU/berlin,%20niedersachsen').then(function (html) {
    // 成功响应(如果CORS允许),但解析目标可能不准确
    var $mainbar = $(html).find('#rt'); // '#rt'并非距离数据所在元素
    if ($mainbar.length) {
        document.write($mainbar.html());
    } else {
        document.write('未能找到指定元素');
    }
}, function () {
    // 错误响应,通常是CORS或网络问题
    document.write('访问被拒绝或发生错误');
});
</script>
登录后复制

专业解决方案:利用距离计算API

鉴于直接网页抓取的诸多局限性,更推荐的解决方案是利用专业的距离计算API。许多提供地理信息服务的平台都开放了API接口,例如distance.to网站本身就基于一个API(可在docs.distance.to/api查看其文档),并且通常通过像RapidAPI这样的API市场进行分发。

使用API的优势包括:

  • 数据结构化: API通常返回JSON或XML等结构化数据,易于解析和处理。
  • 稳定性与可靠性: API接口通常有明确的契约和版本管理,稳定性远高于网页HTML结构。
  • 高效性: 直接获取所需数据,无需下载和解析整个网页。
  • 解决CORS问题: 多数公共API都支持CORS,允许前端应用直接调用。
  • 配额与计费: API服务通常提供免费层级和付费计划,便于管理和控制使用成本。

API接入与配置

要使用距离计算API,通常需要以下步骤:

硅基智能
硅基智能

基于Web3.0的元宇宙,去中心化的互联网,高质量、沉浸式元宇宙直播平台,用数字化重新定义直播

硅基智能 62
查看详情 硅基智能
  1. 注册API平台: 例如在RapidAPI上注册账号。
  2. 订阅API: 找到并订阅distance.to或其他地理距离API。
  3. 获取API Key: 平台会为您生成一个API密钥(X-RapidAPI-Key),这是您调用API的凭证。
  4. 查阅API文档: 了解API的端点(Endpoint)、请求方法(GET/POST)、所需参数(起点、终点、单位等)以及响应数据格式。

一个典型的距离计算API请求可能包含起点、终点和单位参数,并返回一个包含距离数值的JSON对象。

示例:API请求与数据处理

以下是一个使用JavaScript(结合jQuery,与用户原代码风格保持一致)通过API获取并处理距离的示例。请注意,https://api.example.com/distance是一个占位符,您需要替换为实际的API端点,并根据distance.to或其他API的文档调整请求参数和响应解析逻辑。

// 假设的API端点和API密钥
const API_ENDPOINT = 'https://api.example.com/distance'; // 替换为实际的API端点,例如RapidAPI上的distance.to端点
const RAPIDAPI_KEY = 'YOUR_RAPIDAPI_KEY'; // 替换为您的RapidAPI密钥
const RAPIDAPI_HOST = 'distance.p.rapidapi.com'; // 替换为实际的API主机

/**
 * 异步函数:通过API获取两个地点之间的驾车距离
 * @param {string} origin - 起点城市名称或坐标
 * @param {string} destination - 终点城市名称或坐标
 * @returns {Promise<number|null>} 距离(公里)或null(如果发生错误)
 */
async function getDrivingDistance(origin, destination) {
    // 假设API接受 origin, destination, units 参数
    const params = new URLSearchParams({
        origin: origin,
        destination: destination,
        units: 'km' // 请求单位为公里
    });

    try {
        const response = await $.ajax({
            url: `${API_ENDPOINT}?${params.toString()}`,
            method: 'GET',
            headers: {
                'X-RapidAPI-Host': RAPIDAPI_HOST,
                'X-RapidAPI-Key': RAPIDAPI_KEY
            }
        });

        // 假设API响应是一个JSON对象,包含一个 'distance' 字段
        // 例如:{ "distance": 123.45, "unit": "km" }
        if (response && typeof response.distance === 'number') {
            return response.distance;
        } else {
            console.error('API响应格式不正确:', response);
            return null;
        }
    } catch (error) {
        console.error(`获取 ${origin} 到 ${destination} 距离失败:`, error);
        return null;
    }
}
登录后复制

实现城市距离筛选的完整步骤

现在,我们将结合上述API调用方法,实现一个完整的城市距离筛选功能。

1. 准备数据

首先,定义您的“主位置”和待筛选的城市列表。

const mainPosition = "Hameln,Niedersachsen,DEU";
const citiesToFilter = [
    "Bad Eilsen", "Buchholz", "Hannover", "Heeßen", "Luhden", "Samtgemeinde Lindhorst",
    "Beckedorf", "Heuerßen", "Berlin", "Lindhorst", "Lüdersfeld", "Samtgemeinde Nenndorf",
    "Bad Nenndorf", "Haste", "Kassel", "Hohnhorst", "Suthfeld", "Samtgemeinde Niedernwöhren",
    "Lauenhagen", "Meerbeck", "Dortmund", "Niedernwöhren", "Nordsehl", "Pollhagen",
    "Wiedensahl", "Samtgemeinde Nienstädt", "Helpsen", "Hespe", "Frankfurt", "Nienstädt",
    "Freiburg", "Seggebruch", "Potsdam"
];
const MAX_DISTANCE_KM = 75; // 筛选阈值:75公里
登录后复制

2. 异步请求与距离判断

由于API请求是异步的,我们需要使用async/await来处理。为了提高效率,可以并行发起所有城市的距离查询请求。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>城市驾车距离筛选</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        #loading { color: blue; }
        #results { margin-top: 20px; border: 1px solid #ccc; padding: 10px; }
        #results ul { list-style-type: none; padding: 0; }
        #results li { margin-bottom: 5px; }
    </style>
</head>
<body>
    <h1>筛选距离在75公里内的城市</h1>
    <p>主位置:<span id="main-pos-display"></span></p>
    <div id="loading">正在计算距离,请稍候...</div>
    <div id="results">
        <h2>符合条件的城市:</h2>
        <ul id="filtered-city-list">
            <!-- 筛选结果将显示在这里 -->
        </ul>
        <h2>所有城市及距离:</h2>
        <ul id="all-city-distances">
            <!-- 所有城市的距离将显示在这里 -->
        </ul>
    </div>

    <script>
        // 假设的API端点和API密钥(请替换为您的实际信息)
        const API_ENDPOINT = 'https://example-distance-api.com/v1/distance'; // 替换为实际的API端点
        const RAPIDAPI_KEY = 'YOUR_RAPIDAPI_KEY'; // 替换为您的RapidAPI密钥
        const RAPIDAPI_HOST = 'example-distance-api.com'; // 替换为实际的API主机

        const mainPosition = "Hameln,Niedersachsen,DEU";
        const citiesToFilter = [
            "Bad Eilsen", "Buchholz", "Hannover", "Heeßen", "Luhden", "Samtgemeinde Lindhorst",
            "Beckedorf", "Heuerßen", "Berlin", "Lindhorst", "Lüdersfeld", "Samtgemeinde Nenndorf",
            "Bad Nenndorf", "Haste", "Kassel", "Hohnhorst", "Suthfeld", "Samtgemeinde Niedernwöhren",
            "Lauenhagen", "Meerbeck", "Dortmund", "Niedernwöhren", "Nordsehl", "Pollhagen",
            "Wiedensahl", "Samtgemeinde Nienstädt", "Helpsen", "Hespe", "Frankfurt", "Nienstädt",
            "Freiburg", "Seggebruch", "Potsdam"
        ];
        const MAX_DISTANCE_KM = 75; // 筛选阈值:75公里

        // 显示主位置
        $('#main-pos-display').text(mainPosition);

        /**
         * 异步函数:通过API获取两个地点之间的驾车距离
         * @param {string} origin - 起点城市名称或坐标
         * @param {string} destination - 终点城市名称或坐标
         * @returns {Promise<number|null>} 距离(公里)或null(如果发生错误)
         */
        async function getDrivingDistance(origin, destination) {
            const params = new URLSearchParams({
                origin: origin,
                destination: destination,
                units: 'km'
            });

            try {
                const response = await $.ajax({
                    url: `${API_ENDPOINT}?${params.toString()}`,
                    method: 'GET',
                    headers: {
                        'X-RapidAPI-Host': RAPIDAPI_HOST,
                        'X-RapidAPI-Key': RAPIDAPI_KEY
                    }
                });

                // 假设API响应是一个JSON对象,包含一个 'distance' 字段
                // 例如:{ "distance": 123.45, "unit": "km" }
                if (response && typeof response.distance === 'number') {
                    return response.distance;
                } else {
                    console.error('API响应格式不正确:', response);
                    return null;
                }
            } catch (error) {
                console.error(`获取 ${origin} 到 ${destination} 距离失败:`, error);
                // 在API调用失败时,可以返回一个特殊值,或者抛出错误
                return null;
            }
        }

        /**
         * 筛选并显示城市列表
         */
        async function filterAndDisplayCities() {
            $('#loading').show(); // 显示加载提示
            const distancePromises = citiesToFilter.map(city =>
                getDrivingDistance(mainPosition, city + ",Niedersachsen,DEU").then(distance => ({ city, distance }))
            );

            const results = await Promise.allSettled(distancePromises); // 等待所有请求完成

            const filteredCities = [];
            const allCityDistances = [];

            results.forEach(result => {
                if (result.status === 'fulfilled' && result.value.distance !== null) {
                    const { city, distance } = result.value;
                    allCityDistances.push(`<li>${city}: ${distance.toFixed(2)} km</li>`);
                    if (distance <= MAX_DISTANCE_KM) {
                        filteredCities.push(`<li>${city} (${distance.toFixed(2)} km)</li>`);
                    }
                } else {
                    const city = result.reason ? result.reason.city : '未知城市'; // 尝试获取城市名
                    allCityDistances.push(`<li>${city}: 获取距离失败</li>`);
                    console.error(`处理城市 ${city} 失败:`, result.reason);
                }
            });

            // 显示筛选结果
            const $filteredList = $('#filtered-city-list');
            if (filteredCities.length > 0) {
                $filteredList.html(filteredCities.join(''));
            } else {
                $filteredList.html('<li>没有找到符合条件的城市。</li>');
            }

            // 显示所有城市的距离
            $('#all-city-distances').html(allCityDistances.join(''));

            $('#loading').hide(); // 隐藏加载提示
        }

        // 页面加载完成后执行筛选
        $(document).ready(function() {
            filterAndDisplayCities();
        });
    </script>
</body>
</html>
登录后复制

在上述代码中:

  • getDrivingDistance函数负责调用API获取单个城市的距离。
  • filterAndDisplayCities函数是主逻辑,它遍历城市列表,为每个城市调用getDrivingDistance。
  • Promise.allSettled用于等待所有API请求完成,无论成功或失败,这样可以确保所有城市都被处理。
  • 根据返回的距离和MAX_DISTANCE_KM阈值,将城市添加到不同的列表中,并在HTML中显示。

注意事项与最佳实践

  1. API密钥安全: 在客户端(浏览器)代码中直接暴露API密钥存在安全风险,尤其对于付费API。更安全的做法是将API调用放在后端服务器进行,由后端服务器代理请求并管理密钥。如果必须在前端使用,请确保API服务提供商支持基于域名的访问限制,并仅授予必要的权限。
  2. API限额与计费: 大多数API服务都有免费层级和请求限额。在开发和测试阶段注意监控使用量,避免超出限额导致服务中断或产生额外费用。对于

以上就是基于API的城市驾车距离筛选教程的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号