HTML應用指南:利用GET請求獲取全國OPPO官方授權體驗店門店位置信息

本篇文章將利用GET請求從OPPO官方網站或公開接口中獲取官方授權體驗店的分布信息,并通過Python編程語言中的requests庫來實現HTTP請求,從而提取詳細的門店位置數據。隨著OPPO品牌的發展和市場布局的擴展,其官方授權體驗店已經遍布全國各大城市和地區,成為連接消費者與品牌的橋梁。因此,掌握如何高效地從網絡資源中抓取這些信息變得尤為重要。

首先,我們將探討如何使用Python的requests庫發送GET請求以訪問OPPO官方網站或API接口。這包括設置正確的請求頭(headers),以便模擬真實的瀏覽器行為,避免被服務器識別為自動化腳本而拒絕服務。接下來,我們會詳細講解如何解析返回的數據——無論是JSON格式還是HTML頁面內容——從中提取所需的門店信息,如店鋪名稱、地址、經緯度坐標、營業時間等。

在成功獲取數據后,本文還將介紹如何對這些原始數據進行清洗和結構化處理,使其更加適合后續分析。例如,可以將數據轉換成易于管理和查詢的表格形式,或者導入到數據庫中。通過對這些結構化數據的深入分析,我們可以揭示OPPO在全國范圍內的市場滲透策略、不同城市的布局密度及其與當地人口消費特征之間的關系。

OPPO官方授權體驗店門店查詢:OPPO 官方授權體驗店查詢 | OPPO 官方網站

首先,我們找到門店數據的存儲位置,然后看3個關鍵部分標頭、負載、?預覽;

標頭:通常包括URL的連接,也就是目標資源的位置;

負載:對于GET請求:負載通常包含了傳遞的參數,有些網頁負載可能為空,或者沒有負載,因為所有參數都通過URL傳遞,這里我們可以看到城市編碼,當前頁數,還是明文,沒有進行加密;

預覽:指的是對響應內容的快速查看或摘要顯示,可以幫助用戶快速了解返回的數據結構或內容片段;

接下來就是數據獲取部分,先講一下方法思路,一共三個步驟;

方法思路

  1. 找到對應數據存儲位置,獲取所有店鋪列表的相關標簽數據;
  2. 我們通過獲取和改變行政區編碼,來遍歷全國門店數據;
  3. 地址轉經緯度,通過coord-convert庫實現GCJ-02轉WGS84;

第一步:我們先找到對應數據存儲位置,獲取所有門店列表,經過測試,這里可以選擇"通過行政區篩選",再選擇"所有區域",每個區域會根據頁數生成對應數量的html,我們通過修改行政區編碼來進行數據獲取,為了方便我們可以建立一個包含市級行政區????編碼的字典,通過遍歷行政區編碼來查詢全國數據;

通過測試發現非直轄市,數據要想選到"所有區域",就得選擇到市,以河北省為例,就是河北省→石家莊市,當然數據同樣是通過改變編碼進行傳遞的,但是這里是通過查詢一個省,返回一個響應,所以意味著要查詢所有省和自治區,才能知道所有編碼;

但是我國的行政區編碼通常都是一致的,所有我們去中華人民共和國民政部找最新的行政區劃編碼,下載下來;

通常,中國的行政區劃編碼規則如下:

  • 省級:前兩位有效,后四位為 0000(如 110000 北京市)
  • 市級:前四位有效,后兩位為 00,且不是 0000(如 110100 北京市市轄區)
  • 縣級:六位均為有效數字(如 110101 東城區)

因此,我們可以通過判斷編碼是否滿足 XXXX00 且不等于 XXXX00(排除省級)來提取市級編碼;

完整代碼#運行環境 Python 3.11

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import csv# 配置表頭
url = "https://www.mca.gov.cn/mzsj/xzqh/2023/202301xzqh.html"
headers = {"User-Agent": "Mozilla/5.0"}
output_file = "city_codes_2023.csv"# 獲取并解析
print("正在獲取數據...")
res = requests.get(url, headers=headers)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text, 'html.parser')data = []
for row in soup.find_all('tr'):cells = row.find_all('td')if len(cells) >= 3:code = cells[1].get_text(strip=True)name = ''.join(cells[2].get_text().split())  # 清理空白if code.isdigit() and len(code) == 6 and code.endswith('00') and not code.endswith('0000'):if name not in ['市轄區', '縣']:data.append((code, name))# 保存為CSV(帶BOM,兼容Excel)
with open(output_file, 'w', encoding='utf-8-sig', newline='') as f:writer = csv.writer(f)writer.writerow(['編碼', '名稱'])writer.writerows(data)print(f"完成!共提取 {len(data)} 個市級單位,已保存為 '{output_file}'")

獲取數據標簽如下,城市編碼城市名稱,數據保存為city_codes_2023.csv,這里需要把上海(310100)、北京(110100)、天津(120100)、重慶(500100)這些直轄市手動加上,需要注意的是,例如北京市行政區劃代碼為110000,其中,110100為市轄區匯總碼,所以這里直轄市使用的都是市轄區匯總碼;

第二步:利用GET請求獲取所有門店列表,并根據標簽進行保存,另存為csv;

完整代碼#運行環境 Python 3.11

# -*- coding: utf-8 -*-import requests
import csv
import time
from datetime import datetime# ================== 配置 ==================
CSV_INPUT = "city_codes_2023.csv"           # 城市編碼文件(含 "編碼" 列)
CSV_OUTPUT = "oppo_shops_all_cities.csv"    # 輸出文件
API_URL = "https://opsiteapi-cn.oppo.com/api/public/v1/sfa/search"
HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36","Referer": "https://www.oppo.com/"
}
PAGE_SIZE = 100
DELAY = 0.5  # 每個城市請求后延遲0.5秒,禮貌爬取# ================== 讀取城市編碼 ==================
def load_city_codes(filename):codes = []try:with open(filename, 'r', encoding='utf-8-sig') as f:reader = csv.DictReader(f)for row in reader:code = row.get("編碼", "").strip()if code.isdigit() and len(code) == 6:codes.append(code)print(f"加載 {len(codes)} 個城市編碼")except FileNotFoundError:print(f"錯誤:未找到文件 {filename},請確保 city_codes_2023.csv 存在")return []except Exception as e:print(f"讀取城市編碼失敗: {e}")return []return codes# ================== 獲取單個城市的所有門店數據 ==================
def fetch_all_pages(gid):all_shops = []page_no = 1while True:params = {"gid": gid,"shopType": "3","operateStatusList": "2","pageNo": page_no,"pageSize": PAGE_SIZE}try:response = requests.get(API_URL, params=params, headers=HEADERS, timeout=10)response.raise_for_status()data = response.json()if data.get("code") != "0":print(f"API 返回異常 (gid={gid}, page={page_no}): {data.get('message', 'Unknown')}")breakrecords = data["data"]["records"]all_shops.extend(records)# 獲取總頁數total_pages = data["data"]["pages"]print(f"獲取 gid={gid} 第 {page_no}/{total_pages} 頁,共 {len(records)} 條")if page_no >= total_pages:breakpage_no += 1time.sleep(0.1)  # 短暫延遲,避免頻率過高except Exception as e:print(f"請求 gid={gid} 第 {page_no} 頁失敗: {e}")breakreturn all_shops# ================== 保存所有門店數據 ==================
def save_to_csv(all_shops, filename):fieldnames = ["city_gid", "id", "name", "code", "fullShopAddress","lng", "lat", "shopBusinessStart", "shopBusinessEnd", "shopContactNumber"]with open(filename, "w", encoding="utf-8-sig", newline="", errors="replace") as f:writer = csv.DictWriter(f, fieldnames=fieldnames)writer.writeheader()for shop in all_shops:loc = shop.get("locationDTO", {}) or {}writer.writerow({"city_gid": shop.get("city_gid"),  # 標記來源城市"id": shop["id"],"name": shop["name"],"code": shop["code"],"fullShopAddress": loc.get("fullShopAddress", ""),"lng": loc.get("lng", ""),"lat": loc.get("lat", ""),"shopBusinessStart": shop.get("shopBusinessStart", ""),"shopBusinessEnd": shop.get("shopBusinessEnd", ""),"shopContactNumber": shop.get("shopContactNumber", "")})print(f"所有數據已保存至: {filename}")# ================== 主函數 ==================
def main():print(f"開始獲取 OPPO 門店數據 | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")# 1. 加載城市編碼city_codes = load_city_codes(CSV_INPUT)if not city_codes:returnall_shops = []success_count = 0fail_count = 0# 2. 遍歷每個城市for i, gid in enumerate(city_codes, 1):print(f"[{i}/{len(city_codes)}] 正在獲取城市 gid={gid} 的門店數據...")shops = fetch_all_pages(gid)# 添加城市標識for shop in shops:shop["city_gid"] = gidif shops:all_shops.extend(shops)success_count += 1else:fail_count += 1time.sleep(DELAY)  # 控制請求頻率# 3. 保存結果if all_shops:save_to_csv(all_shops, CSV_OUTPUT)print(f"完成!共獲取 {len(all_shops)} 條門店數據,來自 {success_count} 個城市")if fail_count > 0:print(f"{fail_count} 個城市獲取失敗")else:print("未獲取到任何門店數據")# ================== 運行 ==================
if __name__ == "__main__":main()

獲取數據標簽如下,city_gid(行政區id)、id(門店id)、name(門店名稱)、fullShopAddress(門店地址)、lng & lat(地理坐標)、shopBusinessStart(開始營業時間)、shopBusinessEnd(結束營業時間)、shopContactNumber(門店電話),其他一些非關鍵標簽,這里省略;

第三步:坐標系轉換,由于OPPO官方授權體驗店門店數據使用的是高德坐標系(GCJ02),為了在ArcGIS上準確展示而不發生偏移,我們需要將門店的坐標從GCJ02轉換為WGS-84坐標系。我們可以利用coord-convert庫中的gcj2wgs(lng, lat)函數,也可以用免費這個網站:批量轉換工具:地圖坐標系批量轉換 - 免費在線工具;
對CSV文件中的服務網點坐標列進行轉換,完成坐標轉換后,再將數據導入ArcGIS進行可視化;

接下來,我們進行看圖說話:

OPPO官方授權體驗店在中國呈現出明顯的地域性差異。高度集中的現象主要出現在東部和南部地區,尤其是華東、華南以及華中地區,這些區域店鋪的數量顯著多于其他地區。這表明OPPO在這些經濟發達、人口密集且消費能力較強的區域有著更為廣泛的布局。相對而言,稀疏分布的情況則出現在西北、東北及青藏高原等地理環境較為復雜的地區。

具體來看,在東部沿海地區,包括山東、江蘇、浙江、福建和廣東等省份,是體驗店最為密集的地方。這里不僅是我國經濟發展的前沿陣地,也是電子消費品的主要市場之一。城市覆蓋廣的特點不僅體現在省會城市和大城市,還包括了一些中小城市,顯示出OPPO對于該地區市場的重視程度。而在中部地區,如河南、湖北、湖南等地,則構成了次級集中區。盡管店鋪數量不及東部沿海,但依然反映出這些地區擁有較大的市場潛力和發展空間。

相比之下,西部和北部地區的分布顯得較為稀疏。例如新疆、青海、西藏、內蒙古以及黑龍江等省份,由于地理環境、人口密度及經濟發展水平等因素的影響,這里的體驗店數量較少。不過,即便是這些地區,OPPO也傾向于選擇省會城市或較大的城市進行重點布局,如烏魯木齊、呼和浩特等,以確保品牌影響力和服務質量。

影響上述分布的因素眾多,其中經濟因素扮演著重要角色。經濟發展水平商業氛圍較好的地方往往更受青睞;同時,人口因素也不可忽視,人口密度高且年輕人口比例大的地區,對于電子產品的需求量更大。此外,政策因素同樣起到了推動作用,比如部分地區可能享有政府提供的稅收優惠或者租金補貼等支持措施。

展望未來,OPPO有望繼續深化其在東部和中部市場的戰略布局,進一步增加體驗店數量,并提升服務質量。與此同時,隨著國家對西部大開發和東北振興等戰略的支持力度加大,逐步拓展西部和北部市場也將成為可能。通過不斷優化店面選址和運營策略,OPPO可以根據不同地區的市場需求提供更加個性化和優質的服務,滿足廣大消費者的需求。

文章僅用于分享個人學習成果與個人存檔之用,分享知識,如有侵權,請聯系作者進行刪除。所有信息均基于作者的個人理解和經驗,不代表任何官方立場或權威解讀。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917803.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917803.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917803.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Self-RAG:基于自我反思的檢索增強生成框架技術解析

本文由「大千AI助手」原創發布,專注用真話講AI,回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我,一起撕掉過度包裝,學習真實的AI技術! 一、核心定義與原始論文 Self-RAG(Self-Reflective Retri…

【YOLOv8改進 - C2f融合】C2f融合DBlock(Decoder Block):解碼器塊,去模糊和提升圖像清晰度

YOLOv8目標檢測創新改進與實戰案例專欄 專欄目錄: YOLOv8有效改進系列及項目實戰目錄 包含卷積,主干 注意力,檢測頭等創新機制 以及 各種目標檢測分割項目實戰案例 專欄鏈接: YOLOv8基礎解析+創新改進+實戰案例 文章目錄 YOLOv8目標檢測創新改進與實戰案例專欄 介紹 摘要 文…

LLamafactory是什么?

LLamaFactory是一個專注于大型語言模型(LLM)訓練、微調和部署的開源工具平臺,旨在簡化大模型的應用開發流程。?1.核心功能與特點?LlamaFactory(全稱Large Language Model Factory)作為一站式AI開發工具平臺&#xff…

Element Plus編輯表格時的頁面回顯(scope)

1、前提&#xff1a;自定義列模版(把id作為參數&#xff0c;傳遞到調用的edit函數里)<template #default"scope"><el-button type"primary" size"small" click"edit(scope.row.id)"><el-icon><EditPen /><…

河南萌新聯賽2025第四場-河南大學

今天又是坐牢的一次比賽&#xff0c;恭喜獲得本次比賽稱號&#xff1a;掛機王&#xff0c;一個簽到題能卡住兩個小時&#xff0c;這兩個小時簡直坐的我懷疑人生&#xff0c;實在是找不出哪里錯了&#xff0c;后來快結束的時候才發現少了一個等于號&#xff0c;也不至于連簽到題…

【Excel】通過Index函數向下拖動單元格并【重復引用/循環引用】數據源

文章目錄CASE1: 列數據源&#xff0c;向下拖動&#xff0c;每個單元重復N次步驟1&#xff1a;基本的INDEX函數步驟2&#xff1a;添加行號計算步驟3&#xff1a;添加絕對引用以便拖動CASE2:列數據源&#xff0c;向下拖動&#xff0c;每個單元重復1次&#xff0c;周而復始步驟1&a…

潛行者2:切爾諾貝利之心 全DLC 送修改器(S2HOC)免安裝中文版

網盤鏈接&#xff1a; 潛行者2&#xff1a;切爾諾貝利之心 免安裝中文版 名稱&#xff1a;潛行者2&#xff1a;切爾諾貝利之心 全DLC 送修改器&#xff08;S2HOC&#xff09;免安裝中文版 描述&#xff1a; 探索傳奇的《潛行者》世界&#xff0c;同時體驗&#xff1a; 融合…

系統運維之LiveCD詳解

基本概念LiveCD是一個包含完整可運行操作系統的光盤映像&#xff0c;能夠在不影響主機系統的情況下啟動計算機。工作原理系統從LiveCD介質啟動 將必要文件加載到內存中運行 通常使用RAM磁盤作為臨時文件系統 關機后所有更改默認不保存&#xff08;除非特別配置&#xff0…

達夢分布式集群DPC_分布式任務執行拆分流程_yxy

達夢分布式集群DPC_分布式執行計劃執行拆分流程 1 DPC任務拆分原理 1.1 分布式架構思想 1.2 DPC如何實現任務拆分? 2 DPC任務拆分完整示例 2.1 單表查詢 2.1.1 創建分區表,存儲在不同BP上 2.1.2 生成sql的最佳執行計劃 2.1.3 代碼生成并執行、拆分 2.1.3.1 任務拆分步驟 2.1.…

怎么免費建立自己的網站步驟

以下是免費建立個人網站的詳細步驟&#xff0c;結合多種方案和工具推薦&#xff1a; 一、零基礎快速建站方案 ?選擇免費建站平臺? PageAdmin CMS?&#xff1a; 1、提供開源模板&#xff0c;模板可以自定義界面和風格&#xff0c;同時支持原創設計和定制。 2、后臺支持自定義…

使用ASIWebPageRequest庫編寫Objective-C下載器程序

全文目錄&#xff1a;開篇語前言為什么選擇ASIWebPageRequest&#xff1f;安裝ASIWebPageRequest庫編寫下載器程序1. 導入必要的庫2. 創建下載任務3. 設置下載保存路徑4. 發起下載請求5. 更新下載進度6. 處理下載完成7. 處理下載失敗完整代碼示例8. 運行程序總結文末開篇語 哈嘍…

mathtype加載項搞崩了word(上)

一、Mathtype更新后word異常 在mathtype更新后&#xff0c;打開word文件時一直報宏的錯&#xff1a; 點擊“取消”&#xff1a; 點擊“確定”&#xff1a; 點擊“確定”&#xff1a; 點擊“確定”&#xff1a; 還有一堆小彈窗&#xff0c;最后還是能打開word文件&#xff1a; …

算法入門第一篇:算法核心:復雜度分析與數組基礎

引言&#xff1a;為什么需要學習算法&#xff1f; 你可能也發現&#xff0c;即使是社招&#xff0c;面試官也時不時會拋出幾道算法題&#xff0c;從簡單的反轉鏈表到復雜的動態規劃。這常常讓人感到困惑&#xff1a;我一個做游戲開發的&#xff0c;寫好 Unity 的 C# 代碼&…

從“聽指令”到“當參謀”,阿里云AnalyticDB GraphRAG如何讓AI開竅

01、背景 在智能客服與醫療問診領域&#xff0c;用戶模糊描述導致的多輪對話斷裂與語義關聯缺失&#xff0c;長期阻礙決策效率提升。傳統 RAG 技術面臨雙重困境&#xff1a; 單輪檢索局限&#xff1a;當用戶僅反饋“空調制冷效果差”、“持續發熱三天”等模糊信息時&#xff…

javascript常用實例

常見字符串操作字符串反轉const reversed hello.split().reverse().join(); console.log(reversed); // olleh檢查回文字符串function isPalindrome(str) {return str str.split().reverse().join(); }數組處理方法數組去重const unique [...new Set([1, 2, 2, 3])]; // [1,…

RK3568下用 Qt Charts 實現曲線數據展示

實際效果: 在工業監控、智能家居等場景中,實時數據可視化是核心需求之一。本文將介紹如何使用 Qt5 的 Charts 模塊,快速實現一個支持溫度、濕度、大氣壓和噪聲四個參數的實時監測系統,包含曲線動態繪制、坐標軸自適應、多窗口布局等實用功能。 項目背景與目標 環境參數監…

接口自動化測試用例詳解

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快Post接口自動化測試用例Post方式的接口是上傳接口&#xff0c;需要對接口頭部進行封裝&#xff0c;所以沒有辦法在瀏覽器下直接調用&#xff0c;但是可以用Curl命令…

JavaEE初階第十四期:解鎖多線程,從 “單車道” 到 “高速公路” 的編程升級(十二)

專欄&#xff1a;JavaEE初階起飛計劃 個人主頁&#xff1a;手握風云 目錄 一、JUC的常見類 1.1. Callable接口 1.2. ReentrantLock? 1.3. 信號量Semaphore 1.4. CountDownLatch 二、線程安全的集合類 2.1. 多線程環境使用 ArrayList? 2.2. 多線程環境使用哈希表 一、…

什么是RabbitMQ?

什么是RabbitMQ? 一、什么是RabbitMQ? 二、Rabbitmq 的使用場景? 三、RabbitMQ基本概念 四、RabbitMQ的工作模式 1. **簡單隊列模式(Simple Queue)** 2. **工作隊列模式(Work Queue)** 3. **發布/訂閱模式(Publish/Subscribe)** 4. **路由模式(Routing)** 5. **主題…