1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| """ 爬虫脚本:抓取中国进出口贸易近几年走向数据 数据来源:世界银行公开 API(无需登录,按年份返回 JSON) - NE.EXP.GNFS.CD:货物和服务出口额(现价美元) - NE.IMP.GNFS.CD:货物和服务进口额(现价美元) - NE.TRD.GNFS.ZS:进出口总额占 GDP 比重(贸易依存度 %) 运行后输出: 1. 进出口贸易数据_世界银行.csv(原始 + 清洗后数据) 2. 进出口贸易走向趋势.png(趋势图) author: 沐小沐 date: 2026-11-01 """ import time from pathlib import Path
import pandas as pd import requests
BASE_DIR = Path(__file__).parent API_URL = "https://api.worldbank.org/v2/country/CHN/indicator/{code}"
INDICATORS = { "NE.EXP.GNFS.CD": "出口额(美元)", "NE.IMP.GNFS.CD": "进口额(美元)", "NE.TRD.GNFS.ZS": "贸易依存度(%GDP)", }
HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36" }
def fetch_indicator(code: str, date_range: str = "2000:2025") -> pd.DataFrame: """调用世界银行 API 抓取单个指标的年度数据""" params = {"format": "json", "date": date_range, "per_page": 200} try: resp = requests.get(API_URL.format(code=code), params=params, headers=HEADERS, timeout=30) resp.raise_for_status() except requests.RequestException as e: print(f"[错误] 请求指标 {code} 失败:{e}") return pd.DataFrame()
data = resp.json() if not isinstance(data, list) or len(data) < 2 or data[1] is None: print(f"[警告] 指标 {code} 返回数据格式异常,已跳过") return pd.DataFrame()
rows = [{"年份": int(item["date"]), code: item["value"]} for item in data[1] if item["value"] is not None] df = pd.DataFrame(rows) print(f"[完成] 指标 {code} 抓取 {len(df)} 条记录") return df
def main(): all_df = None for code, col_name in INDICATORS.items(): df = fetch_indicator(code) if df.empty: continue df = df.rename(columns={code: col_name}).set_index("年份") all_df = df if all_df is None else all_df.join(df, how="outer") time.sleep(1)
if all_df is None or all_df.empty: print("[错误] 未获取到任何数据,请检查网络") return
result = all_df.sort_index() result["进出口总额(美元)"] = result["出口额(美元)"] + result["进口额(美元)"] result["贸易顺差(美元)"] = result["出口额(美元)"] - result["进口额(美元)"] for col in ["出口额(美元)", "进口额(美元)", "进出口总额(美元)", "贸易顺差(美元)"]: result[col + "(亿美元)"] = (result[col] / 1e8).round(2) result["出口增长率(%)"] = (result["出口额(美元)"].pct_change() * 100).round(2) result["进口增长率(%)"] = (result["进口额(美元)"].pct_change() * 100).round(2) cols = ["出口额(美元)(亿美元)", "进口额(美元)(亿美元)", "进出口总额(美元)(亿美元)", "贸易顺差(美元)(亿美元)", "出口增长率(%)", "进口增长率(%)"] if "贸易依存度(%GDP)" in result.columns: cols.append("贸易依存度(%GDP)") display = result[cols]
csv_path = BASE_DIR / "进出口贸易数据_世界银行.csv" display.to_csv(csv_path, encoding="utf-8-sig", index_label="年份") print(f"[保存] 数据已写入:{csv_path}")
print("\n===== 中国进出口贸易走向(近 10 年)=====") print(display.tail(10).to_string())
try: import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 9), sharex=True) ax1.plot(display.index, display["出口额(美元)(亿美元)"], "o-", color="#d62728", label="出口额") ax1.plot(display.index, display["进口额(美元)(亿美元)"], "o-", color="#1f77b4", label="进口额") ax1.plot(display.index, display["进出口总额(美元)(亿美元)"], "s--", color="#2ca02c", label="进出口总额") ax1.set_ylabel("金额(亿美元)") ax1.set_title("中国进出口贸易走向(2000 年至今,数据来源:世界银行)") ax1.legend() ax1.grid(alpha=0.3)
ax2.bar(display.index, display["贸易顺差(美元)(亿美元)"], color="#ff7f0e", alpha=0.8) ax2.axhline(0, color="gray", linewidth=0.8) ax2.set_xlabel("年份") ax2.set_ylabel("贸易顺差(亿美元)") ax2.grid(alpha=0.3, axis="y")
fig.tight_layout() png_path = BASE_DIR / "进出口贸易走向趋势.png" fig.savefig(png_path, dpi=150) plt.close(fig) print(f"[保存] 趋势图已写入:{png_path}") except ImportError: print("[提示] 未安装 matplotlib,跳过绘图(pip install matplotlib 后可出图)")
if __name__ == "__main__": main()
|