人工智能之編程進階 Python高級

第十一章 過渡項目


以下是 ​5 個由淺入深、覆蓋 Python 核心技能的實戰項目​,每個項目都包含:

  • 🎯 項目目標
  • 🔧 技術棧(知識點)
  • 📦 功能模塊
  • 💡 實現要點與代碼片段
  • 🚀 擴展建議

適合從入門到進階的學習者動手實踐,真正“學以致用”。


🌟 項目一:天氣查詢 CLI 工具(基礎)

🎯 目標

通過命令行輸入城市名,返回當前天氣信息。

🔧 技術棧

  • requests(HTTP 請求)
  • argparse(命令行參數解析)
  • JSON 數據處理
  • 異常處理
  • 免費 API 調用(如 Open-Meteo 或國內聚合 API)

✅ 適合剛學完函數、模塊、異常的新手

📦 功能

  • 輸入城市 → 輸出温度、天氣狀況
  • 支持多城市查詢
  • 網絡錯誤友好提示

💡 實現要點

1. 獲取免費天氣 API

推薦 Open-Meteo(無需 Key):

# 示例:通過經緯度查天氣(需先查城市座標)
def get_weather(lat, lon):
    url = f"https://api.open-meteo.com/v1/forecast"
    params = {
        "latitude": lat,
        "longitude": lon,
        "current_weather": True
    }
    resp = requests.get(url, params=params)
    data = resp.json()
    return data["current_weather"]
2. 命令行接口
import argparse

parser = argparse.ArgumentParser(description="天氣查詢工具")
parser.add_argument("city", help="城市名,如 Beijing")
args = parser.parse_args()

weather = get_weather_by_city(args.city)
print(f"{args.city} 當前温度: {weather['temperature']}°C")
3. 城市轉經緯度(簡化版)

可內置一個小型字典:

CITY_COORDS = {
    "Beijing": (39.9042, 116.4074),
    "Shanghai": (31.2304, 121.4737),
    # 可擴展為讀取 CSV 或調用地理編碼 API
}

🚀 擴展建議

  • 使用 geopy 自動將城市名轉經緯度
  • 添加緩存(避免重複請求)
  • 輸出彩色文字(colorama 庫)
  • 支持歷史天氣、未來預報

🌟 項目二:靜態網頁爬蟲 + 數據分析(中級)

🎯 目標

爬取豆瓣電影 Top 250,保存為 CSV,並做簡單統計。

🔧 技術棧

  • requests(獲取頁面)
  • BeautifulSoup(解析 HTML)
  • pandas(數據分析)
  • csv / json(數據存儲)
  • 正則表達式(可選)

📦 功能

  • 自動翻頁(共 10 頁)
  • 提取:電影名、評分、導演、年份
  • 保存為 movies.csv
  • 分析:平均分、最高分電影、年份分佈

💡 實現要點

1. 爬取單頁
url = "https://movie.douban.com/top250"
headers = {"User-Agent": "Mozilla/5.0"}
resp = requests.get(url, headers=headers)
soup = BeautifulSoup(resp.text, "lxml")

for item in soup.select(".item"):
    title = item.select_one(".title").text
    rating = item.select_one(".rating_num").text
    year = item.select_one(".bd p").text.split()[-1].strip("()")
2. 自動翻頁
all_movies = []
for start in range(0, 250, 25):
    page_url = f"https://movie.douban.com/top250?start={start}"
    movies = parse_page(page_url)
    all_movies.extend(movies)
    time.sleep(1)  # 禮貌延遲
3. 保存與分析
import pandas as pd

df = pd.DataFrame(all_movies)
df.to_csv("douban_top250.csv", index=False)

print("平均分:", df["rating"].astype(float).mean())
print("最高分電影:\n", df.loc[df["rating"].astype(float).idxmax()])

⚠️ 注意

  • 遵守 robots.txt
  • 添加隨機 User-Agent 和延遲,避免被封

🚀 擴展建議

  • matplotlib 可視化評分分佈
  • 存入 SQLite / MySQL
  • 部署為定時任務(每天更新)

🌟 項目三:動態網站爬蟲 —— 模擬登錄 + 數據抓取(中高級)

🎯 目標

自動登錄 GitHub,抓取用户倉庫列表。

🔧 技術棧

  • selenium(瀏覽器自動化)
  • WebDriverWait(顯式等待)
  • Cookie / Session 管理
  • 無頭模式(Headless)

✅ 掌握真實場景中的反爬對抗

📦 功能

  • 自動打開 Chrome
  • 輸入用户名密碼(或 Token)
  • 登錄後跳轉到 /username?tab=repositories
  • 提取倉庫名、語言、Star 數
  • 保存為 JSON

💡 實現要點

1. 啓動瀏覽器(無頭)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
2. 模擬登錄
driver.get("https://github.com/login")
driver.find_element(By.ID, "login_field").send_keys("your_email")
driver.find_element(By.ID, "password").send_keys("your_password")
driver.find_element(By.NAME, "commit").click()

# 等待登錄成功
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "header[role='banner']"))
)

🔐 ​安全建議​:使用 GitHub Personal Access Token 代替密碼!

3. 抓取倉庫
driver.get(f"https://github.com/{username}?tab=repositories")
repos = []
for repo in driver.find_elements(By.CSS_SELECTOR, "li.public"):
    name = repo.find_element(By.CSS_SELECTOR, "h3 a").text
    stars = repo.find_element(By.CSS_SELECTOR, "svg.octicon-star").text.strip()
    repos.append({"name": name, "stars": stars})

🚀 擴展建議

  • pickle 保存登錄後的 Cookie,下次免登錄
  • 支持兩步驗證(需手動掃碼或備用碼)
  • 併發抓取多個用户(配合 threading

🌟 項目四:異步高併發爬蟲(高級)

🎯 目標

併發抓取 100 個網頁,比同步快 10 倍以上。

🔧 技術棧

  • asyncio + aiohttp(異步 HTTP)
  • 協程(coroutine)
  • 限流(semaphore)
  • 異常重試機制

📦 功能

  • 讀取 URL 列表(如 urls.txt
  • 異步併發請求(控制最大併發數)
  • 成功/失敗分別記錄
  • 統計耗時

💡 實現要點

1. 異步請求函數
import aiohttp
import asyncio

async def fetch(session, url):
    try:
        async with session.get(url, timeout=10) as resp:
            return await resp.text()
    except Exception as e:
        return None

async def main():
    urls = [line.strip() for line in open("urls.txt")]
    
    # 限制併發數(防止被封)
    semaphore = asyncio.Semaphore(20)
    
    async def bounded_fetch(url):
        async with semaphore:
            return await fetch(session, url)
    
    async with aiohttp.ClientSession() as session:
        tasks = [bounded_fetch(url) for url in urls]
        results = await asyncio.gather(*tasks)
    
    print(f"成功: {len([r for r in results if r])} / {len(urls)}")

🚀 擴展建議

  • 結合 BeautifulSoup 解析內容
  • 將結果存入數據庫(異步 ORM 如 databases
  • 集成日誌系統(logging

🌟 項目五:Scrapy 專業爬蟲 + Web API(工程化)

🎯 目標

構建一個可配置、可擴展、可部署的新聞爬蟲系統。

🔧 技術棧

  • Scrapy(核心框架)
  • Scrapy-Splashscrapy-selenium(處理 JS)
  • Item Pipeline(數據清洗 + 存儲)
  • FastAPI(提供查詢接口)
  • Docker(容器化部署)

📦 功能

  • 爬取多個新聞站點(如 BBC、Reuters)
  • 提取:標題、正文、發佈時間、URL
  • 去重(基於 URL 指紋)
  • 存入 PostgreSQL
  • 提供 RESTful API 查詢新聞

💡 實現要點

1. Scrapy Spider(多站點)
class NewsSpider(scrapy.Spider):
    name = "news"
    start_urls = [
        "https://www.bbc.com/news",
        "https://www.reuters.com/world/"
    ]

    def parse(self, response):
        if "bbc.com" in response.url:
            yield from self.parse_bbc(response)
        elif "reuters.com" in response.url:
            yield from self.parse_reuters(response)
2. Pipeline 存數據庫
# pipelines.py
class PostgresPipeline:
    def open_spider(self, spider):
        self.conn = psycopg2.connect(...)
        self.cur = self.conn.cursor()

    def process_item(self, item, spider):
        self.cur.execute(
            "INSERT INTO news (title, content, url) VALUES (%s, %s, %s)",
            (item['title'], item['content'], item['url'])
        )
        self.conn.commit()
        return item
3. FastAPI 查詢接口
# api.py
from fastapi import FastAPI
import psycopg2

app = FastAPI()

@app.get("/news")
def get_news(keyword: str = None):
    # 查詢數據庫
    cur.execute("SELECT * FROM news WHERE title ILIKE %s", (f"%{keyword}%",))
    return cur.fetchall()
4. Dockerfile(一鍵部署)
FROM python:3.10
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["scrapy", "crawl", "news"]

🚀 擴展建議

  • 添加 Redis 去重(Scrapy-Redis)
  • 部署到雲服務器(AWS / 阿里雲)
  • 添加定時任務(cron + scrapy crawl)
  • 前端展示(Vue/React)

📌 總結:項目進階路線圖

項目 難度 核心能力
天氣 CLI 工具 基礎語法 + API 調用
豆瓣電影爬蟲 ⭐⭐ 靜態頁解析 + 數據分析
GitHub 登錄爬蟲 ⭐⭐⭐ 動態渲染 + 自動化
異步高併發爬蟲 ⭐⭐⭐⭐ 異步編程 + 性能優化
Scrapy + API 系統 ⭐⭐⭐⭐⭐ 工程化 + 部署

✅ 動手建議

  1. 從項目一做起​,確保每一步都能運行
  2. 代碼提交到 GitHub​,寫好 README
  3. 逐步擴展功能​,不要追求一步到位
  4. 遇到問題查文檔​:官方文檔是最好的老師!

🌈 ​記住​: 編程不是“看會了”,而是“做會了”。 完成一個項目,勝過十篇教程。

後續

由於以上小項目涉及到未學習的內容,比如數據分析等,可以做過渡練習使用。部分代碼已經上傳至gitee,後續會逐步更新,主要受時間原因限制,當然自己也可以克隆到本地學習拓展。

祝你 coding 快樂,早日成為 Python 高手!🐍✨

《Python編程:從入門到實踐》 《利用Python進行數據分析》 《算法導論中文第三版》 《概率論與數理統計(第四版) (盛驟) 》 《程序員的數學》 《線性代數應該這樣學第3版》 《微積分和數學分析引論》 《(西瓜書)周志華-機器學習》 《TensorFlow機器學習實戰指南》 《Sklearn與TensorFlow機器學習實用指南》 《模式識別(第四版)》 《深度學習 deep learning》伊恩·古德費洛著 花書 《Python深度學習第二版(中文版)【純文本】 (登封大數據 (Francois Choliet)) (Z-Library)》 《深入淺出神經網絡與深度學習+(邁克爾·尼爾森(Michael+Nielsen) 》 《自然語言處理綜論 第2版》 《Natural-Language-Processing-with-PyTorch》 《計算機視覺-算法與應用(中文版)》 《Learning OpenCV 4》 《AIGC:智能創作時代》杜雨+&+張孜銘 《AIGC原理與實踐:零基礎學大語言模型、擴散模型和多模態模型》 《從零構建大語言模型(中文版)》 《實戰AI大模型》 《AI 3.0》