编程练习

15 道题覆盖七个项目的核心操作:环境、请求、解析、入库、Scrapy、Flume/Kafka、pandas。每题给思路、参考代码与预期输出。

15 道题基础/进阶/高阶可直接运行

项目一 初识动态网页数据采集与预处理

01

检查本机的采集环境:Python 版本,以及 requests / lxml / bs4 / pandas 是否都能导入。 基础

解题思路sys.version 取版本号;循环里用 __import__ 逐个试着导入,缺库时给提示而不是直接崩掉。
查看参考代码与输出
PYTHON
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]。
查看参考代码与输出
PYTHON
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。
查看参考代码与输出
PYTHON
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 会自动编码。
查看参考代码与输出
PYTHON
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")。
查看参考代码与输出
PYTHON
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)。
查看参考代码与输出
PYTHON
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

把标题与链接配对成字典列表。 进阶

解题思路遍历节点,分别取文本与属性。
查看参考代码与输出
PYTHON
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 里写文件。
查看参考代码与输出
PYTHON
# 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)。
查看参考代码与输出
PYTHON
# 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。
查看参考代码与输出
PYTHON
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()。
查看参考代码与输出
PYTHON
import pandas as pd

df = pd.read_csv("news.csv")
print(df.head())
print(df.info())
👀 预期输出
(前 5 行 + 列名、类型、非空数量)
12

统计缺失值数量并删除含空值的行。 进阶

解题思路isnull().sum() 查看;dropna() 删除。
查看参考代码与输出
PYTHON
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。
查看参考代码与输出
PYTHON
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")。
查看参考代码与输出
PYTHON
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 输出统计。
查看参考代码与输出
PYTHON
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 条,示例:{…}