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

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

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

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

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

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

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

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

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

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

// 这种尝试通常会遇到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('访问被拒绝或发生错误');});

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

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

使用API的优势包括:

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

API接入与配置

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

注册API平台: 例如在RapidAPI上注册账号。订阅API: 找到并订阅distance.to或其他地理距离API。获取API Key: 平台会为您生成一个API密钥(X-RapidAPI-Key),这是您调用API的凭证。查阅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} 距离(公里)或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来处理。为了提高效率,可以并行发起所有城市的距离查询请求。

            城市驾车距离筛选                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; }        

筛选距离在75公里内的城市

主位置:

正在计算距离,请稍候...

符合条件的城市:

所有城市及距离:

// 假设的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} 距离(公里)或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(`
  • ${city}: ${distance.toFixed(2)} km
  • `); if (distance <= MAX_DISTANCE_KM) { filteredCities.push(`
  • ${city} (${distance.toFixed(2)} km)
  • `); } } else { const city = result.reason ? result.reason.city : '未知城市'; // 尝试获取城市名 allCityDistances.push(`
  • ${city}: 获取距离失败
  • `); console.error(`处理城市 ${city} 失败:`, result.reason); } }); // 显示筛选结果 const $filteredList = $('#filtered-city-list'); if (filteredCities.length > 0) { $filteredList.html(filteredCities.join('')); } else { $filteredList.html('
  • 没有找到符合条件的城市。
  • '); } // 显示所有城市的距离 $('#all-city-distances').html(allCityDistances.join('')); $('#loading').hide(); // 隐藏加载提示 } // 页面加载完成后执行筛选 $(document).ready(function() { filterAndDisplayCities(); });

    在上述代码中:

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

    注意事项与最佳实践

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

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

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
    发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1325072.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2025年12月12日 11:40:49
    下一篇 2025年12月12日 11:41:09

    相关推荐

    • 使用PHP PDO连接与操作MySQL数据库:完整教程

      本教程详细指导如何在php中使用pdo(php数据对象)安全高效地连接到mysql数据库并执行数据操作。文章涵盖了从建立数据库连接、配置dsn、处理潜在错误,到执行预处理语句进行数据查询和遍历结果的完整流程,旨在帮助开发者掌握利用pdo进行数据库交互的核心技能。 在现代PHP应用开发中,与数据库进行…

      2025年12月12日
      000
    • PHP数值条件分类函数设计与实现:以数据导入为例

      本文将指导您如何设计一个PHP函数,用于根据特定数值范围对数据进行分类,例如将计算结果标记为“好”、“中等”或“差”。通过结合数值计算、格式化和条件判断,此教程提供了一个清晰的解决方案,适用于数据导入等需要动态分类处理的场景。 理解需求:数值分类逻辑 在许多数据处理场景中,我们经常需要根据某个数值的…

      2025年12月12日
      000
    • 解决PHP中Google Chat Bot Webhook失效问题

      本文旨在帮助开发者解决在使用PHP与Google Chat Bot Webhook集成时遇到的“Invalid request token”错误。通过详细的代码示例和步骤说明,我们将深入探讨如何正确配置cURL请求,并提供一些排查问题的技巧,确保你的PHP应用能够成功地向Google Chat发送消…

      2025年12月12日
      000
    • Laravel资源路由中“缺少必要参数”错误的解析与修复

      本文旨在解决Laravel应用中常见的“缺少必要参数”错误,特别是涉及资源路由和隐式模型绑定时。我们将深入分析该错误通常由路由参数名不匹配引起,并提供一套简洁有效的解决方案,确保route()辅助函数、控制器方法参数与路由定义保持一致,从而顺利实现数据编辑等操作。 在Laravel开发中,当我们在使…

      2025年12月12日
      000
    • 解决 Symfony 控制器中实体自动注入(Autowire)失败问题

      本文旨在解决 symfony 控制器中实体参数自动注入失败的常见问题,即当框架尝试将实体类作为服务进行注入时,报错“no such service exists”。我们将探讨其发生原因,并提供一种直接且稳健的解决方案:通过手动从数据库仓库中获取实体,从而绕过自动注入机制,确保控制器能够正确处理实体操…

      2025年12月12日
      000
    • PHP require_once 文件路径错误问题排查与解决方案

      本文针对 PHP 中 `require_once` 函数报错,提示无法打开文件流的问题,提供详细的排查思路和解决方案。通过分析文件路径、利用 `realpath` 函数,以及理解 `require_once` 和 `include_once` 的区别,帮助开发者快速定位并解决此类问题,确保 PHP …

      2025年12月12日
      000
    • TYPO3自定义表单完成器并发执行异常的解析与最佳实践

      在typo3自定义表单完成器中,当多个请求同时执行时,手动通过`generalutility::makeinstance`实例化extbase仓库可能导致`too few arguments`错误,因为extbase仓库的构造函数需要`objectmanagerinterface`参数。本文将深入分…

      2025年12月12日
      000
    • 使用正则表达式提取Meta Description中的数字:一个教程

      本文介绍了如何使用PHP中的`preg_match`函数,通过正则表达式从HTML的Meta Description标签中提取包含千位分隔符的数字。针对不同的Meta Description内容,提供了一个通用的解决方案,并附带详细的正则表达式解释和PHP示例代码。 在网页抓取或数据分析中,经常需要…

      2025年12月12日
      000
    • JavaScript与PHP交互:动态获取后端数据的方法

      本文旨在阐述在javascript(客户端)中安全有效地获取并使用php(服务器端)后端数据的方法。我们将探讨两种主要策略:通过html中的脚本标签直接嵌入数据(适用于初始加载),以及利用ajax进行异步请求以动态获取数据(适用于用户交互或实时更新场景),并提供详细的代码示例和注意事项,以帮助开发者…

      2025年12月12日
      000
    • 解决PHP中Google Chat Bot Webhook无法正常工作的问题

      本文旨在解决PHP中使用cURL向Google Chat Bot Webhook发送消息时遇到的“Invalid request token”错误。通过分析问题代码和提供可行的解决方案,帮助开发者成功实现PHP与Google Chat的集成,并着重强调了`CURLOPT_POST`选项的重要性以及其…

      2025年12月12日
      000
    • Laravel Eloquent 模型保存时禁止更新时间戳的正确方法

      本文旨在阐明在 Laravel 5.5 中,如何正确地更新 Eloquent 模型而避免更新 `updated_at` 时间戳。我们将对比两种不同的实现方式,解释为何一种方式无效,并提供有效的解决方案,同时深入源码分析原因。 在 Laravel 开发中,我们经常需要更新数据库中的数据,但有时我们不希…

      2025年12月12日
      000
    • 在WordPress导航栏中集成WPML语言切换器:替换元素与短代码实现

      本教程将指导您如何在wordpress网站的导航栏中,用wpml语言切换器替换现有元素(如社交链接)。主要通过编辑主题的`header.php`文件,插入wpml提供的php动作钩子实现,并强调使用子主题以确保更新兼容性。 引言:在WordPress导航中集成自定义元素 在WordPress网站开发…

      2025年12月12日
      000
    • PHP LDAP StartTLS 灵活配置与故障恢复指南

      本文深入探讨了在php中配置ldap认证时,如何灵活处理starttls连接模式,以适应不同客户环境的需求。重点解决了当`ldap_start_tls`尝试失败后,后续的`ldap_bind`操作也随之失败的问题,即使预期是继续以非加密方式通信。解决方案在于,当starttls失败且允许非加密连接时…

      2025年12月12日
      000
    • 在WordPress导航栏中集成WPML语言切换器:PHP实现教程

      本教程详细指导如何在wordpress网站的导航栏中,通过修改主题的`header.php`文件,将现有元素(例如社交链接)替换为wpml语言切换器。我们将利用wpml提供的`do_action(‘wpml_add_language_selector’);`功能,确保多语言站…

      2025年12月12日
      000
    • 整合PHP后端数据到JavaScript:两种实用方法详解

      本教程详细介绍了在web开发中将服务器端php数据传递给客户端javascript的两种主要方法:一是通过在php文件中直接嵌入javascript变量,适用于页面加载时即需的数据;二是通过ajax进行异步通信,适用于动态获取或更新数据。文章将提供具体的代码示例和应用场景分析,帮助开发者高效地实现前…

      2025年12月12日
      000
    • 利用PHP自定义函数在WordPress导入中实现基于数值范围的条件分类

      本教程旨在指导用户如何在wordpress导入流程中,特别是结合wp all import等工具时,通过编写自定义php函数实现数值的条件分类。文章详细阐述了如何根据预设的数值范围(例如0-0.100、0.101-0.200、0.201及以上)将计算结果动态地映射为“good”、“medium”或“…

      2025年12月12日
      000
    • TYPO3 FormFinisher并发执行与Extbase依赖注入的最佳实践

      在typo3 extbase开发中,自定义formfinisher在处理并发提交时,若采用不当的依赖注入方式,可能导致“too few arguments”错误。本文将深入探讨这一问题,解释其根本原因,并提供基于extbase `@inject` 注解的标准化解决方案,确保在多用户同时操作下应用的稳…

      2025年12月12日
      000
    • PHP命令怎么实现自动化测试_PHP命令行单元测试执行

      使用PHPUnit实现PHP自动化测试,首先通过Composer安装并验证版本,然后编写Calculator类及其测试用例CalculatorTest,接着配置phpunit.xml文件以统一管理测试,最后通过phpunit命令行运行测试,支持过滤、覆盖率报告等选项,并可将测试脚本集成到CI/CD流…

      2025年12月12日
      000
    • 解决PHP POST请求405错误:Web服务器环境配置是关键

      当php post请求返回405 not allowed错误时,问题往往不在于php代码本身或cors配置,而在于php脚本未通过正确的web服务器环境(如apache、nginx)运行。本文将深入探讨405错误的原因,强调web服务器在处理http请求中的核心作用,并提供正确的环境配置和故障排查方…

      2025年12月12日
      000
    • 使用PHP进行数值条件分类与数据导入实践

      本教程详细介绍了如何使用php编写自定义函数,根据数值范围将数据分类为“good”、“medium”或“bad”等描述性标签。文章探讨了两种实现方式,并分析了不同边界条件处理的逻辑,旨在帮助用户在数据导入过程中灵活应用条件判断进行数据转换。 在数据导入和处理过程中,我们经常需要根据数值型数据的特定范…

      2025年12月12日
      000

    发表回复

    登录后才能评论
    关注微信