十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent应用指南:获取美宜佳全量门店,4万家看透便利店下沉与集聚

Agent应用指南:获取美宜佳全量门店,4万家看透便利店下沉与集聚 从美宜佳全国 4 万家门店数据我看见了便利店行业的大湾区密码一、引言一家楼下小店藏着 4 万门店的版图提到便利店大多数人脑子里先蹦出来的是 7-11、罗森、全家这些日系招牌。但如果你在华南生活过一定绕不开另一个名字——美宜佳。红底白字、土里土气却在你家楼下、公司门口、地铁口反复出现像空气一样自然。很少有人意识到它的体量这家 1997 年起家于东莞的本土品牌门店数已经悄悄冲到4 万家的量级把一众日系便利店远远甩在身后是国内门店数最多的便利店系统。更反直觉的是它的分布姿势——不是北上广深全国撒网而是把大半个华南焊死在了自己的版图里广东一省就占了全国近一半。前阵子我偶然发现美宜佳官网有个门店地图能按地图看每一家店的位置这篇就用这 4 万条数据拆开看看一家区域便利店是怎么把大湾区做成铁桶的。先抛结论美宜佳不是全国均匀铺开的连锁而是一家把大湾区做成了护城河、再沿交通廊道向周边省份溢出的密度型选手。下面逐个维度拆给你看。二、数据从哪来绕开单位范围查询抓到全量门店先说清楚数据是怎么来的——这关系到后面所有结论的可信度。美宜佳分店地图 (https://ditu.myj.com.cn/)美宜佳官网那个门店地图本质是个按视口懒加载的页面你拖到哪它就只向后台请求当前屏幕框内的门店。普通人永远只能看到本地一小撮。但看代码发现后台接口接收的是任意经纬度矩形压根不校验你是不是真在屏幕上看这块——也就是说只要我把全国地图切成一个个框它就会老老实实把框里的店全吐出来。真正的坑在第二步直接发全国大框后台会因为一次性要塞进约四万家门店而直接 500 报错。这不是禁止大范围查询纯粹是单条响应体量太大顶不住。解决办法很朴素——把全国拆成一堆小框分别查再拼起来。具体三步解耦坐标接口参数就是四个经纬度左下角、右上角没有 token、没有签名、没有必须和视口一致的校验直接发任意矩形即可拆框绕过 500改用 2.5°×2.5° 的小格逐格查最密的珠三角格都能一次返回上万条说明瓶颈只是单响应体量拆小就稳了网格化 自适应细分全国切成网格逐格请求某格若仍返回 500太密就四等分重试递归到最小 0.2° 为止珠三角这类超密区靠这层兜底。每格返回的门店按店号去重合并。附完整抓取脚本可直接运行利用requests库发送HTTP请求对应数据标签并获取所有门店数据并根据标签进行保存另存为csv。importjsonimportosimportcsvimporttimeimportmathimportrequestsfromconcurrent.futuresimportThreadPoolExecutor,as_completedfromthreadingimportLock# 配置区 URLhttps://ditu.myj.com.cn/WebService.asmx/ExecuteOfficeControlFunctionPAGESeed.OfficeControllers.Web.IndexPageLREFhttps://ditu.myj.com.cn/# 中国大致包围盒LNG_MIN,LNG_MAX73.5,135.2LAT_MIN,LAT_MAX3.8,53.6INIT_CELL2.5# 初始网格边长(度) - 约 25 x 20 500 块MIN_CELL0.2# 最小细分边长(度)WORKERS8# 并发线程数REQ_TIMEOUT60# 单请求超时(秒)SLEEP0.02# 单请求后极小停顿(并发已控速)HEADERS{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120 Safari/537.36,Content-Type:application/json; charsetutf-8,Referer:https://ditu.myj.com.cn/,X-Requested-With:XMLHttpRequest,Accept:application/json, text/javascript, */*; q0.01,}# 输出与脚本同级的 myj_stores.csv保存在运行脚本的目录下BASE_DIRos.path.dirname(os.path.abspath(__file__))OUT_CSVos.path.join(BASE_DIR,myj_stores.csv)# 字段映射源字段 - 输出英文列名CSV 表头用英文避免 Excel 编码问题FIELDS[(StoreCode,store_code),(StoreName,store_name),(ShortName,short_name),(Telephone,telephone),(Province,province),(City,city),(Town,town),(Street,street),(DetailAddr,detail_addr),(BaiDuJinDu,baidu_lng),(BaiDuWeiDu,baidu_lat),(TenXunJinDu,tencent_lng),(TenXunWeiDu,tencent_lat),(Hour,business_hours),(CompanyCode,company_code),(Company_Name,company_name),(Status,status),(OpenExpress,open_express),(Category,category),(Introduct,introduction),(Credential,credential),(CreateTime,create_time),(UpdateTime,update_time),]COLS[c[1]forcinFIELDS]# 运行时状态 lockLock()stores{}# StoreCode - store dictstats{ok:0,empty:0,err:0,subdiv:0}seen_cellsset()sessrequests.Session()defclean(v):ifvisNone:returnifisinstance(v,str)andv.strip()in(0001/01/01 00:00:00,):returnreturnvdeffetch_cell(lng1,lat1,lng2,lat2):返回 (status, list_of_stores)。status: ok/empty/errbody{paramJson:json.dumps([PAGE,GetNearStoreList,LREF,lng1,lat1,lng2,lat2,])}try:rsess.post(URL,headersHEADERS,datajson.dumps(body),timeoutREQ_TIMEOUT)exceptException:returnerr,[]ifr.status_code!200:returnerr,[]try:objjson.loads(r.json()[d])exceptException:returnerr,[]resobj.get(Result)ifnotisinstance(res,list):returnerr,[]return(emptyiflen(res)0elseok),resdefprocess_cell(lng1,lat1,lng2,lat2,depth0):key(round(lng1,4),round(lat1,4),round(lng2,4),round(lat2,4))withlock:ifkeyinseen_cells:returnseen_cells.add(key)status,datafetch_cell(lng1,lat1,lng2,lat2)time.sleep(SLEEP)ifstatuserr:cell_wlng2-lng1ifcell_w/2MIN_CELL:withlock:stats[subdiv]1halfcell_w/2halfh(lat2-lat1)/2return[(lng1,lat1,lng1half,lat1halfh),(lng1half,lat1,lng2,lat1halfh),(lng1,lat1halfh,lng1half,lat2),(lng1half,lat1halfh,lng2,lat2),]else:withlock:stats[err]1return[]# ok or emptywithlock:ifstatusempty:stats[empty]1else:stats[ok]1forsindata:codes.get(StoreCode)ifcodeandcodenotinstores:stores[code]sreturn[]defmain():# 初始网格lng_stepsmath.ceil((LNG_MAX-LNG_MIN)/INIT_CELL)lat_stepsmath.ceil((LAT_MAX-LAT_MIN)/INIT_CELL)queue[]foriinrange(lng_steps):forjinrange(lat_steps):lng1LNG_MINi*INIT_CELL lng2min(lng1INIT_CELL,LNG_MAX)lat1LAT_MINj*INIT_CELL lat2min(lat1INIT_CELL,LAT_MAX)queue.append((lng1,lat1,lng2,lat2))print(f初始网格:{lng_steps}x{lat_steps}{len(queue)}块, workers{WORKERS})whilequeue:batchqueue[:2000]queuequeue[2000:]withThreadPoolExecutor(max_workersWORKERS)asex:futs[ex.submit(process_cell,*c)forcinbatch]forfinas_completed(futs):subf.result()ifsub:queue.extend(sub)print(f进度: 已处理块{len(seen_cells)}当前队列{len(queue)}f门店{len(stores)}ok{stats[ok]}empty{stats[empty]}ferr{stats[err]}subdiv{stats[subdiv]},flushTrue,)print(f\n抓取完成。去重后门店总数:{len(stores)})print(stats:,stats)# 清洗 写出 CSV rows[]forsinstores.values():row{c[1]:clean(s.get(c[0]))forcinFIELDS}# 拼接完整地址addr.join(str(row[k])forkin(province,city,town,street,detail_addr)ifrow[k])row[full_address]addr rows.append(row)# 字段顺序full_address 放在 detail_addr 之后cols_outlist(COLS)cols_out.insert(cols_out.index(detail_addr)1,full_address)withopen(OUT_CSV,w,encodingutf-8-sig,newline)asf:wcsv.DictWriter(f,fieldnamescols_out,extrasactionignore)w.writeheader()forrinrows:w.writerow(r)print(f已写出 CSV:{OUT_CSV}(共{len(rows)}家门店))if__name____main__:main()数据会以csv表格的形式保存在运行脚本的目录下表格名myj_stores.csv注文中数据截至 2026 年 8 月数据标签包括StoreCode门店id、StoreName门店名称、full_address门店地址、Telephone电话、business_hours营业时间、lonlat坐标其他一些非关键标签这里省略三、数据全景4 万家店字段比你想象的全这一版抓到的全量门店共40,110 家覆盖22 个省份/直辖市、248 个城市。最让我意外的是字段的完整度地址完整率 100%省、市、区镇、街道、详细门牌一应俱全连瑞江路15号附6号这种级别都给了电话覆盖率 99.0%几乎每家店都带联系电话同时带有百度(BD-09)与腾讯(GCJ-02)双坐标系经纬度、营业时段、所属公司代码等。换句话说这是一份可以直接拿来做空间分析、选址建模、热力可视化的干净数据不是那种只有个名字的残缺表。四、省份版图广东一家独占近半把门店按省份排个序第一眼就会被广东省的数值震住广东19,136 家占全国47.7%——也就是说你每看到两家美宜佳就有一家在广东紧随其后的湖南2,980、广西2,636、湖北1,943、江西1,706全是广东的邻居。这是典型的**“大本营辐射”**以大湾区为圆心沿京广线向北湖南→湖北、沿西江向西广西、沿沪昆向东江西层层溢出。美宜佳没有走北上广深全国撒网的路线而是先把家门口的华南啃透再顺着交通廊道往外渗。这种打法决定了它的门店密度图会极度南重北轻。五、城市格局东莞才是隐藏冠军省份往下看城市会出现一个反直觉的结论门店最多的城市不是广州深圳而是东莞。东莞3,992 家 深圳 3,028 广州 2,556 重庆 1,654 惠州 1,185东莞能压过两座一线城市原因在于它是制造业名城镇街经济发达、外来人口密集、夜间消费旺盛而且——美宜佳的总部就在东莞。主场优势拉满。上面那张气泡图把 248 个城市的门店量成了气泡一眼就能看懂美宜佳的势力范围华南一片玫红密密麻麻往华中、华东还能看到成片的紫与蓝再往北就只剩下零星几个点了。北上广之外的北方省份在这张图上几乎是空白。六、区域密度一个格子顶一个省为了更直观地感受密度差我把全国按4°×4°切成了网格——这个尺度大概相当于一个浙江省大小。然后给每个网格按门店数上色珠三角那个网格15,698 家直接爆表深玫红而同样一个省大小的格子放到西北、华北可能只有零星几家甚至空白。这意味着美宜佳在珠三角塞进的门店数比很多省份全省还多。密度就是它最深的护城河——密集的门店网络摊薄了供应链成本也培养了用户的随手就买习惯。七、七大区占比这是一个关于南方的故事按地理大区归个类结论更清楚华南 22,396 家55.8%一家过半加上华中6,355、华东5,500、西南3,511这四大区吃掉全国91%而华北 西北 东北三个大区合计不到4%。所以美宜佳的扩张史本质上是一个南方故事它用二十多年时间把自己焊死在了北纬 30° 以南。八、开店时间定律近六成 24 小时营业便利店对抗电商的核心壁垒是即时性——你想买的时候它就在。数据也印证了这点约58%23,096 家的门店营业时段以00:00起记多为24 小时营业00:00-24:00剩下约 34% 的非全天门店开门高峰集中在清晨 6—8 点6 点 3,243 家、7 点 8,094 家、8 点 2,407 家。一边是全天候一边是清晨就开门——前者兜住了夜班族和突发需求后者接住了通勤早高峰。便利店这门生意本质上就是在和用户的时间缝隙抢生意。九、集中度头部红海长尾蓝海最后看一个更战略的维度——集中度。把 248 个城市按门店数从多到少排算累计占比前 17 个城市就占了全国一半门店前 68 个城市占八成前 108 个占九成Top10 城市合计 16,506 家占比 41.2%。这曲线说明两件事一是大湾区长沙武汉重庆成都这批头部城市已经卷成了红海二是剩下的140 多个城市只分了全国 10% 的门店——对美宜佳是待开发的腹地对其他品牌则是弯道超车的缝隙。文章仅用于分享个人学习成果与个人存档之用分享知识如有侵权请联系作者进行删除。所有信息均基于作者的个人理解和经验不代表任何官方立场或权威解读。
返回列表