在這篇文章中,我們會一步一步拆解用python爬蟲的方式抓取康是美門市的門市分布資料,主要會用到json套件和requests套件。
一、觀察網頁回傳資料的邏輯
首先康是美的門市查詢網頁,康是美是以縣市做門市分布的分類方式。然後可以看到康是美同一個縣市內的門市沒有再另外做分頁顯示。
接下來,就是輪到強大的開發人員工具登場了。打開開發人員工具(chrome是F12),然後在門市查詢隨便點一個縣市,觀察Network頁籤這邊做了甚麼,找出回傳門市資料的是哪一項工作。
觀察後發現,我們的目標網址會是https://www.cosmed.com.tw/api/getStore.aspx,需要動態改變的參數是c,也就是縣市。
接著我們切換到Preview頁籤後發現,康是美這邊回傳的格式是json,這樣我們後續要處理資料會比較輕鬆,而且回傳格式裡面包含經緯度資料。
二、引入相關套件
由於回傳的格式是json,所以這裡我們只需要引入json和requests套件。json用來轉換格式;requests則是向康是美網頁發出請求並拿到回傳資料。
import requests
import json
三、網頁傳輸參數
(一) URL和傳入參數
前面有提到,這邊需要的是參數c,用來傳入所有縣市,這樣我們就可以用迴圈來爬取所有的門市資料。另外,前面也有看到我們的目標網址,這邊我把它命名為baseURL。
baseURL = 'https://www.cosmed.com.tw/api/getStore.aspx'
我們可以建立一個儲存所有縣市名稱的陣列,把它命名為admins。建立就可以用for迴圈來把縣市名稱動態放入我們要傳入的參數中。
admins = ["臺北市","新北市","基隆市","宜蘭縣","桃園市","新竹市","新竹縣","苗栗縣","臺中市","彰化縣","南投縣","嘉義市","嘉義縣","雲林縣","臺南市","高雄市","屏東縣","臺東縣","花蓮縣","澎湖縣","金門縣","連江縣"]
for city in admins:
baseURL = 'https://www.cosmed.com.tw/api/getStore.aspx'
param = {
"t":"store",
"c":city,
"d":"",
"s":""
}
(二) 送出查詢
這裡就要用到前面import的requests套件,它可以用來發起HTTP request,也就是可以去造訪上面的URL,有點像我們瀏覽網頁。
前面有看到方法是用get,所以這裡就用requests.get( 目標URL, 傳入參數 )。我們的目標URL和傳入參數剛剛都建立好了,這邊只要把參數帶入就好。
而因為回傳的是json格式,所以可以用json.loads( 文字 )來把格式轉為python的dictionary字典格式,這樣才可以繼續用python處理。
response = requests.get( baseURL , params = param )
response.encoding="utf-8"
stores = json.loads(response.text)
四、解析出需要的資訊
因為之後要丟到GIS裡面使用,所以先準備geojson格式,可以先參考任一個point類型的geojson檔案,然後把fetures清空,因為之後我們會把康是美的分店資料丟進這個陣列裡面。
geojson = {
"type": "FeatureCollection",
"name": "conshimei",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": []}
再來就是要找出我們所需要的資訊 ,店名和經緯度,從回傳的json裡面不難看出他們分別是:
店名 : StoreNM
經度 : lng
緯度 : lat
只是這邊要注意,回傳的經度和緯度是文字,因為有被雙引號包起來,所以我們記得要做轉換,python把文字轉浮點數(有小數點)的函式是float( 文字 )。所以在geojson裡面的coordinate我們應該要放的是
[float(s['lng']),float(s['lat'])]
五、整合程式
(一) 使用for迴圈把資料寫入geojson
前一部分已經抓到需要的資訊,其實在這邊,我們只要記得在每一次迴圈,把我們組合出來的物件append到geojson就好。至於儲存分店資訊的物件格式,則一樣參考geojson的檔案格式:
{
"type": "Feature",
"geometry": {
"type": 物件格式(點、線、面),
"coordinates": [經度,緯度]
},
"properties": {
屬性 : 值
}
}
以康是美的例子來說,type會是point,經度和緯度就是前面提到的[float(s[‘lng’]),float(s[‘lat’])],屬性我們只放門市名稱StoreNM。
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [float(s['lng']),float(s['lat'])]
},
"properties": {
"name": s['StoreNM']
}
}
(二) 另存成geojson格式
到這邊,其實我們的程式已已經差不多了,接下只差要把python抓下來的檔案儲存成一個geojson。儲存的方法是先用open( 檔案路徑 , 讀寫方式)打開我們要儲存的json檔案,記得讀寫方式要指定w,也就是會覆寫內容。然後我們要用json.dumps(python字典格式)把字典格式的物件轉換成文字,這樣才可以寫到檔案中。寫檔案的方式是檔案.write(要寫入的文字),最後的最後,離開房門要關燈,寫好檔案也記得把檔案關掉 : 檔案.close()。
f = open("D:\桌面暫存\康是美.geojson",'w')
f.write( json.dumps(geojson) )
f.close()
print("OK")
(三) 完整程式碼
需要時間: 1 小時
用python爬蟲抓取康是美門市位置資料的步驟
- 引用必要套件(requests , json)
觀察回傳資料格式選擇套件
- 對縣市進行迴圈
觀察門市分類的邏輯,並進行迴圈取資料
- 組合參數傳送HTML請求
承上,填入需要的參數
- 取得該縣市所有的經緯度和門市名稱資料
用前述的參數透過python去爬取每個縣市的資料
- 另存成geojson檔案
將前一步驟的資料轉存成geojson格式供QGIS使用
import requests
import json
admins = ["臺北市","新北市","基隆市","宜蘭縣","桃園市","新竹市","新竹縣","苗栗縣","臺中市","彰化縣","南投縣","嘉義市","嘉義縣","雲林縣","臺南市","高雄市","屏東縣","臺東縣","花蓮縣","澎湖縣","金門縣","連江縣"]
geojson = {
"type": "FeatureCollection",
"name": "conshimei",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": []}
for city in admins:
baseURL = 'https://www.cosmed.com.tw/api/getStore.aspx'
param = {
"t":"store",
"c":city,
"d":"",
"s":""
}
response = requests.get( baseURL , params = param )
response.encoding="utf-8"
stores = json.loads(response.text)
for s in stores['data']:
store = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [float(s['lng']),float(s['lat'])]
},
"properties": {
"name": s['StoreNM']
}
}
geojson["features"].append(store)
print( city , " : done" )
f = open("D:\桌面暫存\康是美.geojson",'w')
f.write( json.dumps(geojson) )
f.close()
print("OK")
想知道其他商家的爬蟲,可以參考 : Python網路爬蟲-屈臣氏門市分布
小額支持鍾肯尼
如果我的文章有幫助到你,歡迎你點這裡開啟只要40元的小額贊助連結,可以贊助我一杯咖啡錢;我會更有動力繼續寫作,幫助大家解決更多問題。