聊天視窗

洞見數據:用分析思維駕馭數據科學 - 第 2 章

第二章:數據採集與存儲

發布於 2026-02-27 01:31

# 第二章:數據採集與存儲 > 本章聚焦於**從外部或內部系統取得資料**的技術與流程,並說明如何將資料安全、有效且可追蹤地存放起來。資料採集與存儲是數據科學生命週期中最基礎、最容易被忽略的環節,但它決定了後續清洗、分析與模型開發的品質與可重複性。 --- ## 2.1 API 資料採集 ### 2.1.1 API 類型 | 類型 | 說明 | 適用場景 | |------|------|----------| | RESTful | 基於 HTTP,使用 GET/POST/PUT/DELETE 取得/更新資源 | 公開資料、第三方服務 (OpenWeather, Twitter) | | GraphQL | 一次請求可取得多層結構資料 | 複雜關聯資料、減少多次請求 | | SOAP | XML 交換,具備安全與事務性 | 金融、政府系統 | ### 2.1.2 典型流程 1. **授權**:取得 API 金鑰或 OAuth 令牌。 2. **請求**:使用 `requests` 或 SDK 發送 HTTP 請求。 3. **資料驗證**:檢查 HTTP 狀態碼、JSON 結構、缺失欄位。 4. **儲存**:寫入 CSV、Parquet、資料庫或雲端儲存。 ### 2.1.3 Python 範例(RESTful) python import requests, json, pandas as pd from pathlib import Path API_URL = "https://api.example.com/v1/items" API_KEY = "YOUR_API_KEY" headers = {"Authorization": f"Bearer {API_KEY}", "Accept": "application/json"} params = {"page": 1, "per_page": 100} all_data = [] while True: resp = requests.get(API_URL, headers=headers, params=params) resp.raise_for_status() data = resp.json() all_data.extend(data["items"]) if not data.get("next_page"): break params["page"] = data["next_page"] # 儲存為 Parquet df = pd.DataFrame(all_data) output_path = Path("data/api_items.parquet") df.to_parquet(output_path, engine="pyarrow") print(f"資料已寫入 {output_path}") > **備註**:若 API 速率受限,請加入 `time.sleep()` 或使用 `tenacity` 進行重試機制。 ## 2.2 網頁爬蟲(Web Scraping) ### 2.2.1 基本概念 | 步驟 | 說明 | |------|------| | 1. 目標確定 | 確認要抓取的網頁 URL 與資料結構 | | 2. 請求頁面 | 使用 `requests` 或 `httpx` 取得原始 HTML | | 3. 解析內容 | 透過 `BeautifulSoup`, `lxml` 或 `Scrapy` 解析 DOM | | 4. 儲存資料 | 匯出為 JSON、CSV 或寫入資料庫 | ### 2.2.2 常見陷阱 * **反爬機制**:IP 封鎖、JavaScript 渲染、CAPTCHA。解法:使用 Selenium、Puppeteer 或代理池。 * **版權問題**:遵循網站的 `robots.txt` 與使用條款。 * **資料結構變化**:建立爬蟲可監控頁面結構並自動提醒。 ### 2.2.3 Python 範例(Selenium + BeautifulSoup) python from selenium import webdriver from bs4 import BeautifulSoup import pandas as pd # 1. 開啟瀏覽器 options = webdriver.ChromeOptions() options.add_argument('--headless') driver = webdriver.Chrome(options=options) # 2. 目標頁面 url = "https://example.com/products" driver.get(url) # 3. 等待 JavaScript 生成 driver.implicitly_wait(5) # 4. 取得頁面源碼 html = driver.page_source soup = BeautifulSoup(html, 'lxml') # 5. 解析資料 items = [] for card in soup.select('.product-card'): title = card.select_one('.title').text.strip() price = card.select_one('.price').text.strip() items.append({"title": title, "price": price}) # 6. 儲存 df = pd.DataFrame(items) df.to_csv('data/products.csv', index=False) driver.quit() ## 2.3 結構化資料源與資料庫 | 技術 | 優缺點 | 推薦使用場景 | |------|--------|--------------| | SQL(MySQL, PostgreSQL, SQLite) | ACID 交易、複雜查詢 | 商業報表、交易資料 | | NoSQL(MongoDB, CouchDB, DynamoDB) | 高彈性、水平擴展 | 日誌、非結構化資料 | | OLAP(Snowflake, BigQuery) | 大規模分析、列式存儲 | BI、機器學習預測 | ### 2.3.1 連接示例(Python) python import sqlalchemy from sqlalchemy import create_engine # PostgreSQL engine = create_engine("postgresql+psycopg2://user:pass@host:5432/dbname") # 讀取資料表 df = pd.read_sql('SELECT * FROM sales', engine) > **備註**:對於大批量資料寫入,使用 `COPY` 或批次插入可顯著提升效能。 ## 2.4 雲端儲存與資料湖(Data Lake) ### 2.4.1 主要雲端存儲 | 雲端平台 | 儲存服務 | 特色 | |-----------|----------|------| | AWS | S3, Glacier | 物件存儲、低成本長期備份 | | GCP | Cloud Storage, BigQuery | 與 GCP 服務整合、資料分析即時 | | Azure | Blob Storage, Data Lake Storage Gen2 | 與 Azure 服務、Spark 兼容 | ### 2.4.2 資料湖設計原則 1. **Schema-on-read**:資料可任意儲存,讀取時再決定結構。 2. **分類與權限**:使用文件夾、標籤與 IAM 角色管理存取。 3. **生命周期管理**:自動將冷數據遷移至 Glacier / Archive。 ### 2.4.3 與資料庫連結(Apache Spark) python from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("DataLakeExample") \ .config("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem") \ .getOrCreate() # 讀取 Parquet df = spark.read.parquet("s3a://my-bucket/raw/logs/2023-08/part-0000.parquet") ## 2.5 資料治理 (Data Governance) 與元資料管理 (Metadata Management) ### 2.5.1 為何重要 * **可追蹤性**:確保資料來源、採集時間、變更歷史。 * **品質保證**:定義資料品質指標(完整度、正確性、時間一致性)。 * **合規性**:滿足 GDPR、HIPAA 等法規。 ### 2.5.2 主要概念 | 概念 | 定義 | |------|------| | **資料目錄 (Data Catalog)** | 追蹤資料集、來源、擁有者、版本 | | **資料品質度量** | 完整度、重複度、時效性指標 | | **資料所有權** | 定義資料擁有者、保護等級、審核流程 | ### 2.5.3 工具與平台 | 工具 | 角色 | |------|------| | **OpenMetadata** | 開源資料目錄,支援多雲、資料品質、監控 | | **AWS Glue Data Catalog** | 與 S3/Redshift、Athena 整合 | | **Azure Purview** | 全面治理、合規性管理 | | **Google Data Catalog** | 元資料索引、搜尋 | > **實作範例**:使用 OpenMetadata API 建立資料集元資料。 python import requests, json API_URL = "https://metadata.example.com/api/v1/datasets" TOKEN = "OPENMETADATA_TOKEN" headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"} payload = { "name": "sales_raw", "location": "s3://my-bucket/raw/sales/", "description": "Raw sales data from API", "tags": ["raw", "sales"], } resp = requests.post(API_URL, headers=headers, data=json.dumps(payload)) resp.raise_for_status() print("資料集已註冊於 OpenMetadata") ## 2.5 進階議題:ETL、流式資料與資料治理合流 1. **ETL(Extract‑Transform‑Load)**:傳統批次處理,適合日結、週結報表。 2. **ELT(Extract‑Load‑Transform)**:在資料湖中先寫入原始資料,後續由 SQL/Spark 進行轉換。 3. **流式資料(Kafka, Flink, Cloud Pub/Sub)**:低延遲資料流,適合 IoT、即時監控。 4. **資料管道監控**:使用 Airflow, Prefect, Dagster 進行排程與失敗告警。 --- ## 2.6 小結 * **採集方式選擇**:根據資料型態、更新頻率與合規性決定使用 API、爬蟲、資料庫或雲端物件儲存。 * **儲存格式**:列式格式(Parquet、ORC)適合分析,文本格式(CSV、JSON)適合快速原型。 * **資料治理**:從一開始就建立資料目錄與元資料管理,可避免「資料失蹤」與「品質不一致」問題。 > **建議閱讀**: > * *Designing Data-Intensive Applications* by Martin Kleppmann – 章節 4、6。 > * *Data Engineering on AWS* by Andy McCrory – 針對 S3、Glue、Athena 的實務設計。 --- > **實務提醒**:每次採集完資料後,請務必產生 **資料品質報告**(缺失率、重複率、時間戳對齊)並寫入 `log` 或 `dashboard`,以確保數據來源不會在未發現的情況下改變。