咨询:将网页国债收益率XML完整解析存入SQLite数据库的方案
Hey there, let's break down how to solve your XML parsing and SQLite storage challenge for the daily Treasury yield curve. I've worked on similar data pipeline projects before, so here's a practical, step-by-step approach:
1. Fetch and Parse the XML Data
First, you'll need to pull the XML content and extract the relevant yield data. Let's use Python as an example since it's lightweight for small projects:
- Use
requeststo fetch the XML content (don't forget to handle HTTP errors like timeouts):import requests from xml.etree import ElementTree as ET url = "https://www.treasury.gov/resource-center/data-chart-center/interest-rates/Pages/TextView.aspx?data=yieldAll" response = requests.get(url) response.raise_for_status() # Trigger error if request fails # Parse the XML content root = ET.fromstring(response.content) - The Treasury's XML uses
<entry>tags for each date's data, with<content>holding the yield values. Iterate through entries to extract dates and yields:for entry in root.findall(".//entry"): # Extract date in YYYY-MM-DD format date = entry.find("updated").text.split("T")[0] # Parse the content block (usually a CSV-like string) content = entry.find("content").text yield_data = {} for item in content.split(","): key, value = item.strip().split(": ") # Clean key for database column names (e.g., "1 MO" → "1_month") clean_key = key.lower().replace(" ", "_") # Handle empty values by setting to NULL yield_data[clean_key] = float(value) if value else None
2. Design Your SQLite Database Schema
Create a table that matches the yield curve maturities, with a unique constraint on dates to avoid duplicates:
CREATE TABLE IF NOT EXISTS treasury_yields ( date DATE PRIMARY KEY, 1_month REAL, 2_month REAL, 3_month REAL, 6_month REAL, 1_year REAL, 2_year REAL, 3_year REAL, 5_year REAL, 7_year REAL, 10_year REAL, 20_year REAL, 30_year REAL );
The PRIMARY KEY on date ensures you won't have duplicate entries for the same day—perfect for auto-updates.
3. Insert Parsed Data into SQLite
Use Python's built-in sqlite3 module to connect and insert data. Use INSERT OR REPLACE to update existing entries if the Treasury revises daily data:
import sqlite3 # Connect to database (creates it if missing) conn = sqlite3.connect("treasury_yields.db") cursor = conn.cursor() # Create table if it doesn't exist cursor.execute(""" CREATE TABLE IF NOT EXISTS treasury_yields ( date DATE PRIMARY KEY, 1_month REAL, 2_month REAL, 3_month REAL, 6_month REAL, 1_year REAL, 2_year REAL, 3_year REAL, 5_year REAL, 7_year REAL, 10_year REAL, 20_year REAL, 30_year REAL ); """) # Insert or update entries for entry in root.findall(".//entry"): # ... (parse date and yield_data as before) columns = ", ".join(yield_data.keys()) placeholders = ", ".join(["?" for _ in yield_data.values()]) query = f"INSERT OR REPLACE INTO treasury_yields (date, {columns}) VALUES (?, {placeholders})" cursor.execute(query, (date, *yield_data.values())) # Save changes and close connection conn.commit() conn.close()
4. Automate the Update Process
To make this fully automatic, set up a scheduled task:
- On Linux/macOS: Use
cronto run your script daily after the Treasury updates data (usually around 3 PM ET). Example cron entry:30 19 * * * /usr/bin/python3 /path/to/your/script.py >> /path/to/logfile.log 2>&1 - On Windows: Use Task Scheduler to create a daily task that executes your Python script.
Key Tips to Avoid Headaches
- Handle Missing Values: The Treasury occasionally skips maturities (e.g., 20-year yields were paused for a period). Ensure your code inserts
NULLinstead of crashing when values are empty. - Add Error Handling: Wrap fetch/parse/insert steps in try-except blocks and log errors to a file—this makes debugging failed runs much easier.
- Validate XML Structure: The Treasury might tweak their XML format. Add checks to confirm expected tags exist before parsing (e.g., if
entry.find("updated")returnsNone, log a warning and skip that entry).
内容的提问来源于stack exchange,提问作者Josef Kilany

