项目一 初识动态网页数据采集与预处理
数据来源有哪些、大数据采集与预处理的流程、常用工具,以及在 PyCharm 里把开发环境装好。
本项目学习目标
- 能说出结构化/半结构化/非结构化数据的区别
- 能描述“采集 → 清洗 → 转换 → 加载”的完整流程
- 认识 Flume、Kafka、Scrapy、Pandas、Pig 各自的定位
- 能在 PyCharm 里新建项目、装库、运行第一个脚本
本项目任务导览
初识动态网页数据采集与预处理
了解大数据采集与预处理的整体概念,认识常见数据来源、采集方式与预处理方法,并搭建数据采集与预处理开发环境。
- 项目导言与学习目标
- 任务 1-1 认识大数据采集与预处理
- 任务 1-2 搭建数据采集与预处理开发环境
- 知识拓展与实例案例(3 例)
为什么要采集与预处理数据?学完本项目能获得什么?
在大数据时代,数据是重要的资源。本项目需要采集的数据具有以下特点:
认识大数据采集与预处理; 熟悉数据采集与预处理的方法; 掌握 Python 采集工具的使用方法; 熟练搭建数据采集与预处理开发环境。
能够描述大数据采集与预处理的概念与流程; 能够正确安装并配置 Python 与 PyCharm; 能够搭建面向数据采集与预处理的开发环境。
具有较好的团队精神; 具有高度的责任感; 具备很强的学习和沟通能力; 具有清晰思路、较强的逻辑思维能力。
任务 1-1 认识大数据采集与预处理
数据从哪来?如何采集?采集之后如何预处理?
一、数据来源
了解数据的多种来源,是理解数据采集的前提。
| 数据类型 | 说明 | 典型示例 |
|---|---|---|
| 结构化数据 | 具有固定格式和统一结构,可直接存储于关系型数据库。 | 数据库表、Excel 表格 |
| 半结构化数据 | 具有一定的结构但结构不固定,通常自带描述信息的标签。 | XML、JSON |
| 非结构化数据 | 没有固定结构,无法直接用二维表表示。 | 邮件、文档、图片、音频、视频 |
二、大数据采集
大数据采集主要有网络爬虫采集、Python 采集工具、日志数据采集和商业工具采集等方式。
网络爬虫(Web Crawler)是按照一定规则自动抓取互联网信息的程序或脚本,是动态网页数据采集的重要方式。
- 搜索引擎抓取网页建立索引;
- 采集市场情报、竞品信息与用户评论;
- 为数据分析、科学研究提供原始数据;
- 监控网站内容更新与舆情变化。
Python 生态提供了丰富的网络数据采集工具库:
| 工具 | 说明 |
|---|---|
| Urllib | Python 标准库自带的 HTTP 请求库,无需额外安装即可发起网络请求。 |
| Requests | 简洁易用的第三方 HTTP 请求库,被广泛用于网页数据采集。 |
| Scrapy | 基于 Twisted 异步处理的第三方爬虫框架,适合大规模、结构化的爬取任务。 |
| Beautiful Soup | 用于从 HTML/XML 文件中提取数据的解析库。 |
| XPath | XML 路径语言,用于在 HTML/XML 文档中定位与提取节点。 |
除自行开发外,还可使用商业化的数据采集工具完成网页数据抓取,适合非技术用户快速获取数据。
三、大数据预处理
原始数据往往存在缺失、噪声、格式不统一等问题,需要通过预处理提高数据质量。
数据清洗用于发现并纠正数据中的错误,处理缺失值、重复值和噪声数据。
将来自不同数据源的数据进行合并、统一存储,形成完整、一致的数据集,解决数据孤岛与数据不一致问题。
四、预处理工具
常用的大数据预处理工具包括:
| 工具 | 说明 |
|---|---|
| Pig | Apache 旗下基于 Hadoop 的大规模数据分析平台,以数据流方式分析大规模数据集。 |
| Pandas | Python 核心开源数据分析库,提供丰富的数据处理、清洗与统计分析功能。 |
| ELK | 由 ElasticSearch、Logstash、Kibana 组成的技术栈,用于日志数据的采集、处理与可视化展示。 |
任务 1-2 搭建数据采集与预处理开发环境
使用 PyCharm 作为 Python 集成开发环境,完成数据采集与预处理开发环境搭建。
PyCharm 开发环境
PyCharm 是 JetBrains 出品的 Python IDE,具有智能代码补全、代码检查、项目导航、重构、调试等多种强大功能。
PyCharm 常用快捷键
熟练掌握快捷键可显著提高开发效率。
| 快捷键 | 功能 |
|---|---|
| Ctrl + / | 注释 / 取消注释 |
| Ctrl + Alt + L | 格式化代码 |
| Ctrl + Alt + S | 打开设置 |
| Ctrl + D | 复制当前行或选中内容 |
| Ctrl + Y | 删除当前行 |
| Ctrl + F | 当前文件查找 |
| Ctrl + Shift + F | 全局查找 |
| Ctrl + R | 当前文件替换 |
| Ctrl + Shift + R | 全局替换 |
| Shift + F10 | 运行当前程序 |
| Alt + Shift + F10 | 选择运行配置并运行 |
| Shift + F9 | 调试当前程序 |
| Shift + F6 | 重命名(重构) |
| F11 | 添加 / 移除书签 |
| F5 | 复制文件或目录 |
| F6 | 移动文件或目录 |
知识拓展与实例案例
课堂讲解用:3 个可运行实例 + 知识拓展卡片。
知识拓展
目标:用 Python 最基本的列表与字典,直观理解"结构化 / 半结构化数据"在代码中长什么样,为后续讲解采集与解析做铺垫。
# 结构化数据:类似一张"表格",每一行是一条记录
student_list = [
["学号", "姓名", "成绩"],
["001", "张三", 89],
["002", "李四", 95],
["003", "王五", 78],
]
print("结构化数据(表格形式):")
for row in student_list:
print(row)
# 半结构化数据:JSON 风格的字典,键值对自带"字段名"
student_json = {"001": {"name": "张三", "score": 89},
"002": {"name": "李四", "score": 95}}
print("\n半结构化数据(键值对形式):")
print(student_json["002"]["name"], student_json["002"]["score"])结构化数据(表格形式):
['学号', '姓名', '成绩']
['001', '张三', 89]
['002', '李四', 95]
['003', '王五', 78]
半结构化数据(键值对形式):
李四 95| 代码 | 白话解释 |
|---|---|
| student_list = [ ... ] | 创建一个"列表",里面每一项又是一个小列表,看起来就像一张表格:第一行是表头,后面每一行是一条学生记录。 |
| for row in student_list: | for 循环:从上到下依次取出表格中的每一行,赋给变量 row,然后执行下面缩进的 print 语句。 |
| print(row) | 把取出的这一行打印到屏幕上,所以最后会看到 4 行输出。 |
| student_json = {"001": {...}} | 创建一个"字典",用学号当"钥匙"(键),每个学号对应一个存放姓名、成绩的小字典——这就是 JSON 风格的键值对结构。 |
| student_json["002"]["name"] | 先按钥匙 "002" 找到李四的信息,再取其中的 "name" 字段,得到"李四"。键值对自带字段名,属于半结构化数据。 |
目标:构造一份含缺失、重复、格式异常的数据,用 Python 找出问题——让学生直观看到"为什么要预处理"。
# 模拟一份从网页采集到的"脏数据"
raw = [
{"姓名": "张三", "年龄": 23, "电话": "13800138001"},
{"姓名": "李四", "年龄": None, "电话": "13900139002"}, # 年龄缺失
{"姓名": "张三", "年龄": 23, "电话": "13800138001"}, # 重复记录
{"姓名": "王五", "年龄": "二十五", "电话": "13700137003"}, # 年龄格式异常
]
print("体检报告:")
seen = set()
for i, row in enumerate(raw, 1):
problems = []
if row["年龄"] is None:
problems.append("缺失")
elif not isinstance(row["年龄"], int):
problems.append("格式异常")
key = (row["姓名"], row["电话"])
if key in seen:
problems.append("重复")
seen.add(key)
status = "、".join(problems) if problems else "正常"
print(f"第{i}条记录:{row['姓名']} → {status}")体检报告:
第1条记录:张三 → 正常
第2条记录:李四 → 缺失
第3条记录:张三 → 重复
第4条记录:王五 → 格式异常| 代码 | 白话解释 |
|---|---|
| raw = [ {...}, {...} ] | 模拟一份从网页采集的原始数据:第 2 条年龄是 None(缺失)、第 3 条与第 1 条完全一样(重复)、第 4 条年龄写成了中文"二十五"(格式异常)——这就是"脏数据"。 |
| seen = set() | 创建一个空集合 seen,用来记录"已经见过的记录"。集合的特点是元素不会重复,适合做去重标记。 |
| for i, row in enumerate(raw, 1): | 逐条取出数据,enumerate 顺便给每条编个号(从 1 开始),i 是编号,row 是当前这条记录。 |
| if row["年龄"] is None: | 判断年龄是不是 None(空值)。None 表示"这里没有数据",是缺失问题。 |
| elif not isinstance(row["年龄"], int): | isinstance(x, int) 判断 x 是不是整数。年龄不是整数(比如是字符串"二十五"),说明格式异常。 |
| key = (row["姓名"], row["电话"]) | 把"姓名+电话"拼成一个组合当作"指纹",用于判断两条记录是不是同一个人。 |
| if key in seen: ... / seen.add(key) | 如果这个"指纹"已经出现过,说明重复;否则把它记进 seen,供后面的记录比对。 |
| "、".join(problems) if problems else "正常" | 把发现的问题列表用顿号连成字符串(如"缺失、重复");没有问题就显示"正常"。三元表达式,相当于 if 的简写。 |
目标:用 Pandas 完成"读取 → 去重 → 填充 → 保存"的最小清洗闭环,让学生提前感知数据预处理的完整套路。
# 安装:pip install pandas
import pandas as pd
# 1. 读取:从 CSV 读入数据表
df = pd.read_csv("news.csv")
# 2. 检查:看看有没有缺失和重复
print("缺失统计:\n", df.isna().sum())
print("数据行数:", len(df))
# 3. 去重:删除重复记录
df = df.drop_duplicates()
# 4. 填充:用"未知"填补缺失的标题
df["标题"] = df["标题"].fillna("未知")
# 5. 保存:输出清洗后的结果
df.to_csv("news_clean.csv", index=False)
print("清洗完成,剩余行数:", len(df))缺失统计:
标题 2
发布时间 0
阅读量 1
数据行数: 120
清洗完成,剩余行数: 112| 代码 | 白话解释 |
|---|---|
| import pandas as pd | 导入 pandas 表格处理库(需先 pip install pandas),全课程统一用 pd 缩写。 |
| df = pd.read_csv("news.csv") | 读取 news.csv 文件,转成"数据表"对象 DataFrame 存入 df。从此以后,df 就是一张可以整体操作的表格。 |
| df.isna().sum() | isna() 把每个空单元格标记为 True,sum() 把每列的空值数加起来。输出"标题 2、阅读量 1"说明这两列分别缺 2 条、1 条数据。 |
| len(df) | 统计表格有多少行(120 条原始记录)。 |
| df = df.drop_duplicates() | 删除完全重复的行。注意一定要写回 df,因为 drop_duplicates 返回新表、不改原表。120 条变 112 条,说明去掉了 8 条重复。 |
| df["标题"] = df["标题"].fillna("未知") | 取"标题"列,把空值填成"未知"。这样即使有些新闻没抓到标题,也不会让后面的程序崩溃。 |
| df.to_csv("news_clean.csv", index=False) | 把清洗后的表格存成新文件 news_clean.csv。index=False 表示不保存行号(第 0、1、2…列)。 |