Python調(diào)用API接口實現(xiàn)規(guī)范獲取官方數(shù)據(jù)
爬蟲有個明顯局限——一旦網(wǎng)頁結(jié)構(gòu)更新(比如按鈕位置、標(biāo)簽名變化),代碼就會失效。而很多平臺會提供更規(guī)范的數(shù)據(jù)獲取方式:API接口(Application Programming Interface,應(yīng)用程序編程接口)。這篇我們就學(xué)習(xí)“API接口調(diào)用”,用Python對接公開API(以天氣API、新聞API為例),掌握“構(gòu)造請求、解析響應(yīng)、處理認(rèn)證”的核心邏輯,高效獲取官方數(shù)據(jù),同時規(guī)避爬蟲的不穩(wěn)定問題。
一、先搞懂:什么是API接口?為什么用它?
1. API接口的本質(zhì)
簡單說,API是平臺對外開放的“數(shù)據(jù)通道”——平臺將數(shù)據(jù)整理成結(jié)構(gòu)化格式(如JSON),通過接口供開發(fā)者調(diào)用,開發(fā)者不用解析網(wǎng)頁,直接按規(guī)則發(fā)送請求就能拿到干凈數(shù)據(jù)。
舉個例子:你想獲取北京的天氣,不用爬取天氣網(wǎng)站,直接調(diào)用“高德天氣API”,發(fā)送包含“城市名”的請求,接口會返回類似這樣的結(jié)構(gòu)化數(shù)據(jù)(JSON格式):
{
"status": "1",
"count": "1",
"info": "OK",
"infocode": "10000",
"lives": [
{
"province": "北京",
"city": "北京市",
"adcode": "110000",
"weather": "晴",
"temperature": "25",
"winddirection": "東北",
"windpower": "2級",
"humidity": "45",
"reporttime": "2024-06-10 14:00:00"
}
]
}
直接提取lives[0]["weather"]就能拿到“晴”,比爬蟲解析HTML高效得多。
2. API接口的優(yōu)勢(對比爬蟲)
| 對比維度 | 網(wǎng)頁爬蟲 | API接口調(diào)用 |
|---|---|---|
| 數(shù)據(jù)格式 | 非結(jié)構(gòu)化(HTML),需解析 | 結(jié)構(gòu)化(JSON/XML),直接提取 |
| 穩(wěn)定性 | 依賴網(wǎng)頁結(jié)構(gòu),易失效 | 平臺維護(hù),結(jié)構(gòu)穩(wěn)定 |
| 效率 | 需下載完整HTML,較慢 | 只返回目標(biāo)數(shù)據(jù),較快 |
| 合規(guī)性 | 可能違反網(wǎng)站協(xié)議 | 官方授權(quán),合規(guī)安全 |
3. 核心概念:RESTful API與HTTP請求方法
目前主流的API是“RESTful API”,基于HTTP協(xié)議設(shè)計,常用4種請求方法對應(yīng)不同操作:
- GET:獲取數(shù)據(jù)(最常用,如“獲取天氣”“獲取新聞列表”);
- POST:提交數(shù)據(jù)(如“創(chuàng)建用戶”“提交表單”);
- PUT:更新數(shù)據(jù)(如“修改用戶信息”);
- DELETE:刪除數(shù)據(jù)(如“刪除一條記錄”);
我們?nèi)腴T階段重點(diǎn)掌握GET請求(獲取數(shù)據(jù))。
4. 準(zhǔn)備工作:獲取API Key(接口認(rèn)證)
大部分公開API需要“API Key”(類似鑰匙)驗證身份,避免惡意調(diào)用。我們以“高德開放平臺”為例,申請免費(fèi)天氣API Key:
- 注冊高德開放平臺賬號;
- 進(jìn)入“控制臺”→“應(yīng)用管理”→“創(chuàng)建應(yīng)用”(隨便填名稱,如“Python學(xué)習(xí)”);
- 應(yīng)用創(chuàng)建后,點(diǎn)擊“添加Key”,選擇“Web服務(wù)”,提交后得到API Key(后續(xù)代碼會用到)。
二、實戰(zhàn)1:調(diào)用高德天氣API,獲取實時天氣
我們先從簡單的“獲取城市實時天氣”入手,掌握API調(diào)用的核心流程:解讀接口文檔→構(gòu)造請求URL→發(fā)送請求→解析JSON響應(yīng)→提取數(shù)據(jù)。
1. 第一步:解讀接口文檔(關(guān)鍵?。?/h3>
調(diào)用API前必須看文檔,明確“請求URL、參數(shù)、響應(yīng)格式”。高德實時天氣API文檔地址:https://lbs.amap.com/api/webservice/guide/api/weatherinfo/
核心信息整理:
請求URL:https://restapi.amap.com/v3/weather/weatherInfo
必選參數(shù):
key:你的API Key(身份驗證);city:城市編碼(如北京110000,可查“高德城市編碼表”,或用城市名拼音);
可選參數(shù):
extensions:返回類型(base返回實時天氣,all返回預(yù)報,默認(rèn)base);
響應(yīng)格式:JSON(結(jié)構(gòu)化數(shù)據(jù))。
2. 第二步:代碼實現(xiàn)(獲取實時天氣)
import requests
import logging
import json
# 1. 配置日志(記錄請求過程和錯誤)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
def get_real_time_weather(api_key, city):
"""
調(diào)用高德天氣API,獲取指定城市的實時天氣
參數(shù):
api_key:高德開放平臺的API Key
city:城市編碼(如110000)或城市名拼音(如beijing)
返回:
成功返回天氣字典(含天氣、溫度、風(fēng)向等),失敗返回None
"""
try:
logging.info(f"開始獲取{city}的實時天氣")
# 2. 構(gòu)造請求參數(shù)(必選參數(shù)+可選參數(shù))
params = {
"key": api_key,
"city": city,
"extensions": "base" # base=實時天氣,all=預(yù)報+實時
}
# 3. 發(fā)送GET請求(API接口常用GET方法獲取數(shù)據(jù))
api_url = "https://restapi.amap.com/v3/weather/weatherInfo"
response = requests.get(
url=api_url,
params=params, # params參數(shù)會自動拼接到URL后(如?key=xxx&city=110000)
timeout=10 # 超時時間10秒,避免長時間等待
)
# 4. 檢查請求是否成功(HTTP狀態(tài)碼200表示正常)
response.raise_for_status() # 若狀態(tài)碼非200(如400、403),拋出HTTPError
# 5. 解析JSON響應(yīng)(將JSON字符串轉(zhuǎn)為Python字典)
response_data = response.json() # requests內(nèi)置JSON解析方法,比json.loads更方便
logging.debug(f"API響應(yīng)原始數(shù)據(jù):{json.dumps(response_data, ensure_ascii=False, indent=2)}")
# 6. 檢查API業(yè)務(wù)狀態(tài)(非HTTP狀態(tài)碼,是接口自定義的狀態(tài))
# 高德API中,status=1表示成功,0表示失敗,infocode返回錯誤碼
if response_data.get("status") != "1":
error_info = response_data.get("info", "未知錯誤")
error_code = response_data.get("infocode", "未知錯誤碼")
logging.error(f"API業(yè)務(wù)失?。簕error_info}(錯誤碼:{error_code})")
print(f"? 天氣獲取失敗:{error_info}(錯誤碼:{error_code})")
return None
# 7. 提取核心天氣數(shù)據(jù)(從響應(yīng)中找到需要的字段)
lives = response_data.get("lives", [])
if not lives:
logging.error("API響應(yīng)中未找到天氣數(shù)據(jù)(lives字段為空)")
print("? 天氣獲取失?。何凑业侥繕?biāo)城市的天氣數(shù)據(jù)")
return None
# 整理需要的字段(去掉冗余信息)
weather_info = {
"省份": lives[0].get("province", "未知"),
"城市": lives[0].get("city", "未知"),
"天氣": lives[0].get("weather", "未知"),
"溫度(℃)": lives[0].get("temperature", "未知"),
"風(fēng)向": lives[0].get("winddirection", "未知"),
"風(fēng)力": lives[0].get("windpower", "未知"),
"濕度(%)": lives[0].get("humidity", "未知"),
"更新時間": lives[0].get("reporttime", "未知")
}
logging.info(f"成功獲取{weather_info['城市']}的實時天氣")
return weather_info
except requests.exceptions.HTTPError as e:
logging.error(f"HTTP請求錯誤:{e}")
print(f"? HTTP錯誤:{e}(可能API Key無效或URL錯誤)")
return None
except requests.exceptions.Timeout as e:
logging.error(f"請求超時:{e}")
print(f"? 超時錯誤:{e}(請檢查網(wǎng)絡(luò)連接)")
return None
except Exception as e:
logging.error(f"天氣獲取未知錯誤:{e}", exc_info=True)
print(f"? 未知錯誤:{e}(請查看日志獲取詳情)")
return None
# 測試:獲取北京的實時天氣(替換為你的API Key)
if __name__ == "__main__":
# ?。?!替換為你自己的高德API Key(從控制臺獲?。?
MY_AMAP_API_KEY = "你的API Key"
city_code = "110000" # 北京的城市編碼,也可嘗試"shanghai"(上海拼音)
weather_data = get_real_time_weather(MY_AMAP_API_KEY, city_code)
if weather_data:
print("\n" + "="*50)
print("?? 實時天氣信息")
print("="*50)
for key, value in weather_data.items():
print(f"{key}:{value}")
print("="*50)
3. 運(yùn)行結(jié)果(示例)
若API Key有效且網(wǎng)絡(luò)正常,會輸出類似:
==================================================
?? 實時天氣信息
==================================================
省份:北京
城市:北京市
天氣:晴
溫度(℃):25
風(fēng)向:東北
風(fēng)力:2級
濕度(%):45
更新時間:2024-06-10 14:00:00
==================================================
三、實戰(zhàn)2:調(diào)用新聞API,獲取熱點(diǎn)新聞列表
我們再實戰(zhàn)一個“獲取新聞列表”的API,學(xué)習(xí)“分頁獲取數(shù)據(jù)”(一次獲取多頁新聞),并將結(jié)果保存到Excel,銜接第十篇的數(shù)據(jù)處理知識。
1. 準(zhǔn)備:選擇公開新聞API
我們用“聚合數(shù)據(jù)”的免費(fèi)新聞API(需注冊申請API Key):
注冊聚合數(shù)據(jù)賬號(https://www.juhe.cn/);
搜索“新聞頭條”API,進(jìn)入詳情頁點(diǎn)擊“申請數(shù)據(jù)”,獲取API Key;
查看接口文檔,核心信息:
- 請求URL:
http://v.juhe.cn/toutiao/index - 必選參數(shù):
key(你的API Key)、type(新聞類型,如top=頭條,shehui=社會); - 可選參數(shù):
page(頁碼,默認(rèn)1)、page_size(每頁條數(shù),默認(rèn)20); - 響應(yīng)格式:JSON。
2. 代碼實現(xiàn)(獲取新聞+保存Excel)
import pandas as pd
from datetime import datetime
def get_news_list(api_key, news_type="top", page=1, page_size=20):
"""
調(diào)用聚合新聞API,獲取指定類型的新聞列表(支持分頁)
參數(shù):
api_key:聚合數(shù)據(jù)的API Key
news_type:新聞類型(top=頭條,shehui=社會,guonei=國內(nèi),guoji=國際)
page:頁碼(默認(rèn)1)
page_size:每頁條數(shù)(默認(rèn)20,最大不超過100)
返回:
成功返回新聞列表(每個元素為字典),失敗返回None
"""
try:
logging.info(f"開始獲取{news_type}類型新聞(第{page}頁,每頁{page_size}條)")
# 構(gòu)造請求參數(shù)
params = {
"key": api_key,
"type": news_type,
"page": page,
"page_size": page_size
}
# 發(fā)送GET請求
api_url = "http://v.juhe.cn/toutiao/index"
response = requests.get(api_url, params=params, timeout=10)
response.raise_for_status()
# 解析JSON響應(yīng)
response_data = response.json()
logging.debug(f"新聞API響應(yīng)(第{page}頁):{json.dumps(response_data, ensure_ascii=False, indent=2)}")
# 檢查API業(yè)務(wù)狀態(tài)(聚合API中,error_code=0表示成功)
if response_data.get("error_code") != 0:
error_info = response_data.get("reason", "未知錯誤")
logging.error(f"新聞API業(yè)務(wù)失敗:{error_info}(錯誤碼:{response_data.get('error_code')})")
print(f"? 新聞獲取失?。簕error_info}")
return None
# 提取新聞列表(response_data["result"]["data"]是新聞數(shù)據(jù))
news_list = response_data.get("result", {}).get("data", [])
if not news_list:
logging.warning(f"第{page}頁未獲取到新聞數(shù)據(jù)")
print(f"?? 第{page}頁未找到新聞數(shù)據(jù)")
return []
# 整理新聞字段(去掉冗余字段,保留核心信息)
cleaned_news = []
for news in news_list:
cleaned_news.append({
"新聞標(biāo)題": news.get("title", "未知"),
"新聞來源": news.get("source", "未知"),
"發(fā)布時間": news.get("date", "未知"),
"新聞鏈接": news.get("url", "未知"),
"是否熱點(diǎn)": "是" if news.get("is_hot", 0) == 1 else "否",
"爬取時間": datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 記錄爬取時間
})
logging.info(f"成功獲取第{page}頁新聞,共{len(cleaned_news)}條")
return cleaned_news
except Exception as e:
logging.error(f"新聞獲取錯誤(第{page}頁):{e}", exc_info=True)
print(f"? 第{page}頁新聞獲取失?。簕e}")
return None
def save_news_to_excel(news_list, excel_path="熱點(diǎn)新聞列表.xlsx"):
"""將新聞列表保存到Excel文件"""
if not news_list:
logging.warning("無新聞數(shù)據(jù)可保存")
print("?? 無新聞數(shù)據(jù),無需保存")
return False
try:
logging.info(f"開始將新聞數(shù)據(jù)保存到Excel:{excel_path}")
# 轉(zhuǎn)換為DataFrame
df = pd.DataFrame(news_list)
# 保存到Excel(index=False:不保存行索引)
df.to_excel(excel_path, index=False, engine="openpyxl")
logging.info(f"成功保存{len(df)}條新聞到Excel:{excel_path}")
print(f"\n? 新聞數(shù)據(jù)已保存到:{excel_path}(共{len(df)}條)")
return True
except Exception as e:
logging.error(f"新聞保存Excel失?。簕e}", exc_info=True)
print(f"? 保存Excel失?。簕e}")
return False
# 完整流程:獲取多頁新聞+保存Excel
if __name__ == "__main__":
print("="*60)
print("?? 新聞API調(diào)用工具(支持分頁獲取)")
print("="*60)
# ?。?!替換為你自己的聚合數(shù)據(jù)API Key
MY_JUHE_API_KEY = "你的API Key"
news_type = "top" # 新聞類型:top=頭條,shehui=社會
total_pages = 2 # 計劃獲取2頁新聞
# 1. 循環(huán)獲取多頁新聞
all_news = []
for page in range(1, total_pages + 1):
page_news = get_news_list(
api_key=MY_JUHE_API_KEY,
news_type=news_type,
page=page,
page_size=10 # 每頁10條,2頁共20條
)
if page_news is None:
continue # 失敗則跳過該頁
all_news.extend(page_news) # 合并多頁數(shù)據(jù)
# 延遲1秒,避免頻繁請求被限制
import time
time.sleep(1)
# 2. 保存到Excel
if all_news:
save_news_to_excel(all_news)
print("\n?? 程序執(zhí)行完畢!")
3. 運(yùn)行結(jié)果
項目文件夾中會生成“熱點(diǎn)新聞列表.xlsx”,打開后可看到包含“新聞標(biāo)題、來源、發(fā)布時間”等字段的結(jié)構(gòu)化數(shù)據(jù),可直接用于后續(xù)分析(如統(tǒng)計新聞來源分布)。
四、API調(diào)用常見問題與解決方案
在實戰(zhàn)中可能遇到各種問題,這里整理3個高頻問題及解決方法:
1. 問題1:API Key無效(錯誤碼401/403)
原因:API Key填寫錯誤、未激活、超過調(diào)用次數(shù)限制;
解決:
- 檢查API Key是否與申請平臺一致(如高德的Key不能用于聚合數(shù)據(jù));
- 登錄平臺控制臺,確認(rèn)Key已激活,且調(diào)用次數(shù)未用完;
- 若Key過期,重新申請新Key。
2. 問題2:請求參數(shù)錯誤(錯誤碼400)
原因:缺少必選參數(shù)、參數(shù)格式錯誤(如城市編碼填成中文);
解決:
- 對照接口文檔,確認(rèn)所有必選參數(shù)已傳入(如
key、city); - 檢查參數(shù)格式(如頁碼必須是整數(shù),城市編碼需符合平臺規(guī)范);
- 打印
response.text查看原始響應(yīng),平臺通常會返回具體錯誤描述(如“city參數(shù)格式錯誤”)。
3. 問題3:響應(yīng)數(shù)據(jù)解析失敗(KeyError)
原因:API響應(yīng)結(jié)構(gòu)與預(yù)期不符(如字段名變化);
解決:
- 打印
response.json()查看完整響應(yīng),確認(rèn)字段名是否正確(如預(yù)期lives字段,實際是weather); - 用
dict.get()方法獲取字段(如data.get("lives", [])),避免直接用data["lives"]導(dǎo)致KeyError; - 檢查接口文檔是否有更新,確認(rèn)最新的響應(yīng)結(jié)構(gòu)。
總結(jié)
這篇我們掌握了API接口調(diào)用的核心技能,串聯(lián)了前序多個知識點(diǎn):
- 核心流程:解讀文檔→構(gòu)造參數(shù)→發(fā)送請求→解析JSON→提取數(shù)據(jù),相比爬蟲更規(guī)范高效;
- 實用技能:處理API認(rèn)證(API Key)、分頁獲取數(shù)據(jù)、錯誤碼判斷,應(yīng)對實戰(zhàn)常見問題;
到此這篇關(guān)于Python調(diào)用API接口實現(xiàn)規(guī)范獲取官方數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Python調(diào)用API接口獲取數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flaks基礎(chǔ)之在URL中添加變量的實現(xiàn)詳解
這篇文章主要介紹了在python開發(fā)中,F(xiàn)laks框架之上在URL鏈接中添加變量的實現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09
從入門到實戰(zhàn)詳解Python Streamlit如何快速將腳本變成交互式網(wǎng)頁應(yīng)用
這篇文章主要為大家詳細(xì)介紹了如何使用Python Streamlit實現(xiàn)快速將腳本變成交互式網(wǎng)頁應(yīng)用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2025-12-12
Python設(shè)計實現(xiàn)的計算器功能完整實例
這篇文章主要介紹了Python設(shè)計實現(xiàn)的計算器功能,結(jié)合完整實例形式分析了Python3.5實現(xiàn)計算器功能的正則、字符串及數(shù)值運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
Python有關(guān)Unicode UTF-8 GBK編碼問題詳解
本文主要介紹了Python有關(guān)Unicode UTF-8 GBK編碼問題詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
python 實現(xiàn)二維字典的鍵值合并等函數(shù)
今天小編就為大家分享一篇python 實現(xiàn)二維字典的鍵值合并等函數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12
Python實現(xiàn)學(xué)生成績管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Python實現(xiàn)學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

