文章目录
目标
技术栈
requests
(HTTP 请求)
argparse
(命令行参数解析)
适合刚学完函数、模块、异常的新手
功能
实现要点
推荐 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"]
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")
可内置一个小型字典:
CITY_COORDS = {
"Beijing": (39.9042, 116.4074),
"Shanghai": (31.2304, 121.4737),
# 可扩展为读取 CSV 或调用地理编码 API
}
扩展建议
geopy 自动将城市名转经纬度colorama 库)目标
技术栈
requests
(获取页面)
BeautifulSoup
(解析 HTML)
pandas
(数据分析)
csv
/
json
(数据存储)
功能
movies.csv实现要点
url = "https://movie.douban.com/top250"
headers = {"User-Agent": "Mozilla/5.0"}
resp = requests.get(url, headers=headers)
以下是 5 个由浅入深、覆盖 Python 核心技能的实战项目,每个项目都包含:
适合从入门到进阶的学习者动手实践,真正“学以致用”。
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???? 项目三:动态网站爬虫 —— 模拟登录 + 数据抓取(中高级难度)
???? 目标
自动登录 GitHub,获取用户仓库列表。
???? 技术栈
seleniumWebDriverWait? 掌握实际场景中的反爬虫策略应对
???? 功能
自动启动 Chrome 浏览器
输入用户名密码(或 Token)
登录后转至
/username?tab=repositories???? 实现要点
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支持两步验证(需手动扫码或备用码)并发抓取多个用户(配合
threading)
并发获取 100 个网页,速度比同步方式快超过 10 倍。
asyncio + aiohttp
读取 URL 列表(例如
urls.txt),异步并发请求(限制最大并发量),成功/失败分别记录,统计耗时。
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(核心框架)Scrapy-Splash或scrapy-selenium(处理 JS)Item Pipeline(数据清洗 + 存储)FastAPI(提供查询接口)Docker(容器化部署)抓取多个新闻网站(例如 BBC、Reuters),提取标题、正文、发布时间和 URL,基于 URL 指纹去重,存入 PostgreSQL,并提供 RESTful API 查询新闻。
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)
# 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
# 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()
FROM python:3.10
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["scrapy", "crawl", "news"]
| 项目 | 难度 | 核心能力 |
|---|---|---|
| 天气 CLI 工具 | ? | 基础语法 + API 调用 |
| 豆瓣电影爬虫 | ?! | 静态页解析 + 数据分析 |
| GitHub 登录爬虫 | ??? | 动态渲染 + 自动化 |
| 异步高并发爬虫 | ???? | 异步编程 + 性能优化 |
| Scrapy + API 系统 | ????? | 工程化 + 部署 |
编程不是“看会了”,而是“做会了”。完成一个项目,胜过十篇教程。
由于以上小项目涉及未学习的内容,比如数据分析等,可以作为过渡练习使用。部分代码已上传至 gitee,后续会逐步更新,主要受时间限制,当然自己也可以克隆到本地学习拓展。
祝你 coding 快乐,早日成为 Python 高手!?????
扫码加好友,拉您进群



收藏
