Bootstrap

HTML应用指南:利用GET请求获取星巴克门店数据

本篇文章,我们将探究GET请求的实际应用,我们使用Python的requests库通过GET请求抓取星巴克门店信息。星巴克作为全球知名的咖啡连锁品牌,其门店分布广泛,获取这些门店的信息对于数据分析、市场研究以及商业决策都具有重要意义。我们将以获取全国的星巴克门店为例,详细讲解请求的构建、数据的提取和保存。

星巴克官方地址:门店查询 | 星巴克

老规矩,我们第一步先找到门店数据的存储位置,然后看3个关键部分标头、负载、 预览;

标头:通常包括URL的连接,也就是目标资源的位置;

负载:对于GET请求:负载通常包含了传递的参数,有些网页负载可能为空,或者没有负载,因为所有参数都通过URL传递;

 预览:指的是对响应内容的快速查看或摘要显示,可以帮助用户快速了解返回的数据结构或内容片段;

接下来就是数据获取部分,先讲一下方法思路,一共三个步骤;

方法思路

  1. 检查请求是否成功;
  2. 获取标签(提取数据);
  3. 配置负载参数,并最终将所有提取的数据保存到Excel文件中;

第一步部分:对于GET请求,找到有效数据的URL之后,接下来,就是获取数据的步骤,先打印是否响应和响应内容;

完整代码#运行环境 Python 3.11

import requests


def fetch_data():
    url = "https://www.starbucks.com.cn/api/stores/nearby?lat=39.75601&lon=116.173119&limit=30&locale=ZH&features=&radius=10000"

    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功

        # 打印原始响应内容
        print("原始响应内容:", response.text)

    except requests.exceptions.RequestException as e:
        print("请求异常:", e)


if __name__ == "__main__":
    fetch_data()

第二步部分:如果我们收到信息code = 200,意味着请求成功,接下来就可以开始分析响应内容,双击URL并查看字段,识别出所有感兴趣的字段,确认每个字段的数据类型(字符串、数字、布尔值等),如果响应是嵌套的JSON对象或数组,注意其层次结构 ,有助于后续保存csv;

从数据结构可以看出来包含门店的id、name、address(门店地址)、city(所在城市)、streetAddressLine(门店具体地址)、(longitude,latitude)门店经纬度、(closeTime、openTime)门店营业时间、features(门店标签,OG"外带",DL外送,MOP"移动支付"等标签);

第三步部分:我们通过配置坐标参数(lon,lat),输出限制(limit)和查询半径(radius),另外我们获取的地理坐标系是高德坐标系,需要将GCJ02坐标转换为WGS84坐标;

我们看一下官方宣传就知道全国大概的门店数量,这边我们把限制设为1万家,即limit= 10000,查询半径,因为半径的查询单位是米,我们把查询范围设置的特别大,比如一个极大的值如10000000米(即1万公里),我们就可以查询全国范围内的星巴克门店分布了,这里的坐标我们可以通过高德的坐标拾取,随意拾取一个坐标点,因为查询范围非常大,所以点的位置就不太重要了;

完整代码#运行环境 Python 3.11

import requests
import pandas as pd
from datetime import datetime
import math

# 坐标转换参数
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626  # π
a = 6378245.0  # 长半轴
ee = 0.00669342162296594323  # 扁率

# 存储获取的门店信息
content_list = []


def gcj02towgs84(lng, lat):
    """
    GCJ02(火星坐标系)转GPS84
    :param lng: 火星坐标系的经度
    :param lat: 火星坐标系的纬度
    :return: WGS84坐标系的经纬度
    """
    if out_of_china(lng, lat):
        return lng, lat
    dlat = transformlat(lng - 105.0, lat - 35.0)
    dlng = transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lat + dlat
    mglng = lng + dlng
    return [lng * 2 - mglng, lat * 2 - mglat]


def transformlat(lng, lat):
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 * math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lat * pi) + 40.0 * math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 * math.sin(lat * pi / 30.0)) * 2.0 / 3.0
    return ret


def transformlng(lng, lat):
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 * math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lng * pi) + 40.0 * math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 * math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
    return ret


def out_of_china(lng, lat):
    """
    判断是否在国内,不在国内不做偏移
    """
    if lng < 72.004 or lng > 137.8347:
        return True
    if lat < 0.8293 or lat > 55.8271:
        return True
    return False


def starbucks(lon, lat):
    url = "https://www.starbucks.com.cn/api/stores/nearby"

    headers = {
        "Cookie": "YOUR_COOKIE_HERE",  # 替换为您的Cookie
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
        # 示例User-Agent
    }
    data = {
        "lat": lat,
        "lon": lon,
        "limit": "10000",
        "locale": "ZH",
        "features": "",
        "radius": "10000000",
    }

    response = requests.get(url=url, headers=headers, params=data)

    if response.status_code == 200:  # 检查请求是否成功
        content_json = response.json()

        # 处理返回的数据
        for store in content_json['data']:
            # 获取门店的经纬度
            store_lng = store['coordinates']['longitude']
            store_lat = store['coordinates']['latitude']
            # 转换坐标
            wgs_lng, wgs_lat = gcj02towgs84(store_lng, store_lat)
            store['coordinates']['longitude'] = wgs_lng
            store['coordinates']['latitude'] = wgs_lat

        df = pd.json_normalize(content_json['data'], errors='ignore')
        content_list.append(df)
        print(f"获取到 {len(content_json['data'])} 家星巴克门店")
    else:
        print(f"请求失败,状态码: {response.status_code}")


if __name__ == '__main__':
    # 上海市的经纬度
    shanghai_coords = [
        (121.4737, 31.2304)  # 坐标中心的经纬度
    ]

    # 创建一个DataFrame来存储经纬度
    df_coords = pd.DataFrame(shanghai_coords, columns=['lon', 'lat'])

    for index, row in df_coords.iterrows():
        starbucks(row['lon'], row['lat'])

    # 合并所有获取的DataFrame
    df = pd.concat(content_list, ignore_index=True)

    # 将 DataFrame 保存为 excel 文件
    curr_time = datetime.now()
    timestamp = datetime.strftime(curr_time, '%Y-%m-%d %H-%M-%S')  # 添加格式字符串
    df.to_excel(f"星巴克门店{timestamp}.xlsx", index=False)
    print("保存完成!")

脚本运行结束我们就可以获取到所有星巴克门店的位置信息和其他标签信息;

数据会以Excel表格的形式,保存在运行脚本的目录下;

我们把坐标信息放到argis进行可视化,可以看到星巴克门店在空间上的分布情况;

文章仅用于分享个人学习成果与个人存档之用,分享知识,如有侵权,请联系作者进行删除。所有信息均基于作者的个人理解和经验,不代表任何官方立场或权威解读。

;