编程练习
15 道题覆盖七个项目的核心操作:环境、请求、解析、入库、Scrapy、Flume/Kafka、pandas。每题给思路、参考代码与预期输出。
项目一 初识动态网页数据采集与预处理
01
检查本机的采集环境:Python 版本,以及 requests / lxml / bs4 / pandas 是否都能导入。 基础
解题思路sys.version 取版本号;循环里用 __import__ 逐个试着导入,缺库时给提示而不是直接崩掉。
查看参考代码与输出
import sys
print(sys.version.split()[0])
for m in ("requests", "lxml", "bs4", "pandas"):
try:
__import__(m)
print(m, "OK")
except ImportError:
print(m, "未安装")👀 预期输出
3.10.11 requests OK lxml OK bs4 OK pandas OK
项目二 动态网页数据采集
02
用 requests 抓取一个网页,打印状态码与前 50 个字符。 基础
解题思路requests.get(url) 返回 Response,用 .status_code 与 .text[:50]。
查看参考代码与输出
import requests
r = requests.get("https://www.python.org", timeout=10)
print(r.status_code)
print(r.text[:50])👀 预期输出
200 <!doctype html> <html lang="en">…
03
给请求加上 User-Agent 请求头,避免被识别为脚本。 基础
解题思路headers 参数传字典,键名写 User-Agent。
查看参考代码与输出
import requests
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
r = requests.get("https://www.python.org", headers=headers, timeout=10)
print(r.status_code)👀 预期输出
200
04
用中文关键字搜索并抓取结果(参数编码)。 进阶
解题思路把参数放进 params 字典,requests 会自动编码。
查看参考代码与输出
import requests
params = {"q": "人工智能"}
r = requests.get("https://www.baidu.com/s", params=params,
headers={"User-Agent": "Mozilla/5.0"}, timeout=10)
print(r.url, r.status_code)👀 预期输出
https://www.baidu.com/s?q=%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD 200
项目三 动态网页数据解析
05
用 XPath 提取页面中所有链接的 href。 基础
解题思路html.xpath("//a/@href")。
查看参考代码与输出
from lxml import etree
html = etree.HTML('<a href="/a">A</a><a href="/b">B</a>')
print(html.xpath("//a/@href"))👀 预期输出
['/a', '/b']
06
用 BeautifulSoup 提取所有新闻标题文本。 进阶
解题思路soup.select("h2.title") 得到列表,再 get_text(strip=True)。
查看参考代码与输出
from bs4 import BeautifulSoup
html = '<h2 class="title">新闻一</h2><h2 class="title">新闻二</h2>'
soup = BeautifulSoup(html, "html.parser")
print([h.get_text(strip=True) for h in soup.select("h2.title")])👀 预期输出
['新闻一', '新闻二']
07
把标题与链接配对成字典列表。 进阶
解题思路遍历节点,分别取文本与属性。
查看参考代码与输出
from bs4 import BeautifulSoup
html = '<li><a href="/1">一</a></li><li><a href="/2">二</a></li>'
soup = BeautifulSoup(html, "html.parser")
rows = [{"title": a.get_text(strip=True), "url": a["href"]} for a in soup.select("li a")]
print(rows)👀 预期输出
[{'title': '一', 'url': '/1'}, {'title': '二', 'url': '/2'}]项目四 基于框架实现动态网页数据采集与存储
08
Scrapy 中把抓到的数据交给 Pipeline 存入 CSV,关键配置是什么? 进阶
解题思路settings.py 里启用 ITEM_PIPELINES;Pipeline 的 process_item 里写文件。
查看参考代码与输出
# settings.py
ITEM_PIPELINES = {"myproj.pipelines.CsvPipeline": 300}
# pipelines.py
class CsvPipeline:
def open_spider(self, spider):
self.f = open("out.csv", "w", encoding="utf-8")
def process_item(self, item, spider):
self.f.write(f"{item['title']},{item['url']}\n")
return item👀 预期输出
Scrapy 运行结束后生成 out.csv
项目五 动态网页访问日志数据采集
09
写一个 Flume 配置:netcat source → memory channel → logger sink,把 44444 端口收到的每行日志打印出来。 基础
解题思路Flume 配置就三段:sources / channels / sinks,最后把三段串起来(source 接 channel、sink 接 channel)。
查看参考代码与输出
# nc-flume.conf
a1.sources = r1
a1.channels = c1
a1.sinks = k1
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.sinks.k1.type = logger
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1👀 预期输出
$ bin/flume-ng agent -n a1 -c conf -f nc-flume.conf -Dflume.root.logger=INFO,console
(另一端 telnet localhost 44444 输入 hello)
INFO ... Event: { headers:{} body: 68 65 6C 6C 6F hello }10
用 kafka-python 消费 logs 主题的前 5 条消息并打印偏移量。 进阶
解题思路KafkaConsumer 指定 topic、bootstrap_servers、earliest;循环里计数到 5 就退出,记得 close。
查看参考代码与输出
from kafka import KafkaConsumer
consumer = KafkaConsumer(
"logs",
bootstrap_servers=["localhost:9092"],
auto_offset_reset="earliest",
consumer_timeout_ms=5000,
)
n = 0
for msg in consumer:
print(msg.offset, msg.value.decode("utf-8", "ignore"))
n += 1
if n >= 5:
break
consumer.close()👀 预期输出
0 192.168.1.20 - - [2025-07-01] "GET /news/1.html" 200 1 192.168.1.21 - - [2025-07-01] "GET /news/2.html" 200 …(共 5 条)
项目六 动态网页数据预处理
11
读一个 CSV,查看前 5 行与基本信息。 基础
解题思路read_csv + head() + info()。
查看参考代码与输出
import pandas as pd
df = pd.read_csv("news.csv")
print(df.head())
print(df.info())👀 预期输出
(前 5 行 + 列名、类型、非空数量)
12
统计缺失值数量并删除含空值的行。 进阶
解题思路isnull().sum() 查看;dropna() 删除。
查看参考代码与输出
import pandas as pd
df = pd.read_csv("news.csv")
print(df.isnull().sum())
df = df.dropna()
print(len(df))👀 预期输出
(各列空值数 + 清洗后行数)
13
按“来源”分组统计新闻条数,按数量降序取前 5。 进阶
解题思路groupby("来源").size() + sort_values。
查看参考代码与输出
import pandas as pd
df = pd.read_csv("news.csv")
stat = df.groupby("来源").size().sort_values(ascending=False).head(5)
print(stat)👀 预期输出
来源 校园网 42 教务处 18 …
14
把发布时间转成日期类型,并按月份统计发稿量。 高阶
解题思路pd.to_datetime + dt.to_period("M")。
查看参考代码与输出
import pandas as pd
df = pd.read_csv("news.csv")
df["发布时间"] = pd.to_datetime(df["发布时间"], errors="coerce")
print(df["发布时间"].dt.to_period("M").value_counts().sort_index())👀 预期输出
2025-07 36 2025-08 41
项目七 综合实训:校园新闻动态采集与分析系统
15
把“采集 → 解析 → 清洗 → 统计”写成四个函数并用 main 串起来。 高阶
解题思路分工:fetch 返回 HTML、parse 返回列表、clean 返回 DataFrame、report 输出统计。
查看参考代码与输出
import requests, pandas as pd
from bs4 import BeautifulSoup
def fetch(url):
return requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, timeout=10).text
def parse(html):
soup = BeautifulSoup(html, "html.parser")
return [{"标题": a.get_text(strip=True), "链接": a["href"]} for a in soup.select("a.news")]
def clean(rows):
df = pd.DataFrame(rows).drop_duplicates()
return df.dropna()
def main():
rows = parse(fetch("https://example.edu/news"))
df = clean(rows)
print(f"共 {len(df)} 条,示例:{df.iloc[0].to_dict() if len(df) else '无'}")
if __name__ == "__main__":
main()👀 预期输出
共 N 条,示例:{…}