目前,我已成功使用python從競爭對手的網站上抓取資料以查找商店資訊。該網站有一張地圖,您可以在其中輸入郵政編碼,它會告訴您我當前位置區域內的所有商店。該網站使用此鏈接發送 GET 請求以提取存盤資料:
https://www.homedepot.com/StoreSearchServices/v2/storesearch?address=37028&radius=50&pagesize=30
我的目標是抓取所有商店資訊,而不僅僅是想象中的郵政編碼 = 12345 & pagesize = 30。我應該如何獲取所有商店資訊?遍歷郵政編碼資料集以拉出所有商店會更好,還是有更好的方法來做到這一點?我已經嘗試擴展超過 30 個頁面大小,但看起來這是請求的限制。
uj5u.com熱心網友回復:
這個 url 給出了 JSON,"currentPage":1這意味著它可以使用某種分頁。
我添加了&page=2,它似乎有效
第 1 頁:
https://www.homedepot.com/StoreSearchServices/v2/storesearch?address=37028&radius=250&pagesize=40&page=1
第2頁:
https://www.homedepot.com/StoreSearchServices/v2/storesearch?address=37028&radius=250&pagesize=40&page=2
第 3 頁:
https://www.homedepot.com/StoreSearchServices/v2/storesearch?address=37028&radius=250&pagesize=40&page=3
對于測驗,我使用更大range=250的來獲取 JSON"recordCount":123
我發現它也適用于pagesize=40.
對于更大的價值,它會發送帶有錯誤訊息的 JSON。
編輯:
最小的作業代碼:
頁面塊請求沒有User-Agent
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0',
}
url = 'https://www.homedepot.com/StoreSearchServices/v2/storesearch'
payload = {
'address': 37028,
'radius': 250,
'pagesize': 40,
'page': 1,
}
page = 0
while True:
page = 1
print('--- page:', page, '---')
payload['page'] = page
response = requests.get(url, params=payload, headers=headers)
data = response.json()
print(data['searchReport'])
if "stores" not in data:
break
for number, item in enumerate(data['stores'], 1):
print(f'{number:2} | phone: {item["phone"]} | zip: {item["address"]["postalCode"]}')
結果:
--- page: 1 ---
{'recordCount': 123, 'currentPage': 1, 'storesPerPage': 40}
1 | phone: (931)906-2655 | zip: 37040
2 | phone: (270)442-0817 | zip: 42001
3 | phone: (615)662-7600 | zip: 37221
4 | phone: (615)865-9600 | zip: 37115
5 | phone: (615)228-3317 | zip: 37216
6 | phone: (615)269-7800 | zip: 37204
7 | phone: (615)824-2391 | zip: 37075
8 | phone: (615)370-0730 | zip: 37027
9 | phone: (615)889-7211 | zip: 37076
10 | phone: (615)599-4578 | zip: 37064
etc.
--- page: 2 ---
{'recordCount': 123, 'currentPage': 2, 'storesPerPage': 40}
1 | phone: (662)890-9470 | zip: 38654
2 | phone: (502)964-1845 | zip: 40219
3 | phone: (812)941-9641 | zip: 47150
4 | phone: (812)282-0470 | zip: 47129
5 | phone: (662)349-6080 | zip: 38637
6 | phone: (502)899-3706 | zip: 40207
7 | phone: (662)840-8390 | zip: 38866
8 | phone: (502)491-3682 | zip: 40220
9 | phone: (870)268-0619 | zip: 72404
10 | phone: (256)575-2100 | zip: 35768
etc.
如果您想保持原樣,DataFrame則可能首先將所有專案放在串列中,然后將此串列轉換為DataFrame
# --- before loop ----
all_items = []
page = 0
# --- loop ----
while True:
# ... code ...
for number, item in enumerate(data['stores'], 1):
print(f'{number:2} | phone: {item["phone"]} | zip: {item["address"]["postalCode"]}')
all_items.append(item)
# --- after loop ----
import pandas as pd
df = pd.DataFrame(all_items)
print(df)
因為 JSON 保留address為目錄{'postCode': ... , ...},所以某些列可能將其作為目錄
print(df.iloc[0])
storeId 0726
name Clarksville, TN
phone (931)906-2655
address {'postalCode': '37040', 'county': 'Montgomery'...
coordinates {'lat': 36.581677, 'lng': -87.300826}
services {'loadNGo': True, 'propane': True, 'toolRental...
storeContacts [{'name': 'Brenda G.', 'role': 'Manager'}]
storeHours {'monday': {'open': '6:00', 'close': '21:00'},...
url /l/Clarksville-TN/TN/Clarksville/37040/726
distance 32.530296
proDeskPhone (931)920-9400
flags {'bopisFlag': True, 'assemblyFlag': True, 'bos...
marketNbr 0019
axGeoCode 00
storeTimeZone CST6CDT
curbsidePickupHours {'monday': {'open': '09:00', 'close': '18:00'}...
storeOpenDt 1998-08-13
storeType retail
toolRentalPhone NaN
見:{ }在address, services,storeHours等
它可能還需要將其轉換為單獨的行。
df['address'].apply(pd.Series)
并將其與原始df
df2 = pd.concat( [df, df['address'].apply(pd.Series)], axis=1 )
與其他列相同的方式。
uj5u.com熱心網友回復:
我之前遇到過同樣的問題,您提出了一種解決方案,
我建議在 domain/sitemap.xml 和 domain/robots.txt 中搜索可用的商店。
有時資料也存盤在 .js 請求中,因此打開網路選項卡并搜索其中一個商店的 ID。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/486855.html
