最近经常看到一个问题:为什么很多人学 Python 学了大半年,还是只会 print("Hello World")?
原因多数不是不努力,而是方向错了。一上来就啃语法书、刷理论视频,学了 list、dict、tuple,却不知道这些东西在爬虫和数据分析里到底怎么用。等到真要写一个抓取脚本、处理一份 CSV,脑子还是空的。
这次我们换一种思路来聊 Python:不按教材章节走,而是把爬虫和数据分析作为主线,需要什么语法就补什么语法。从环境配置、基础语法、请求库使用、HTML 解析、数据清洗到可视化,一条线走完。文章里会给出可直接运行的代码、完整的测试步骤和常见报错排查清单,读完你至少能自己写一个简单的数据采集和处理脚本,而不是停留在“看得懂、写不出”的阶段。
先说明一下这篇内容的适用范围:零基础、想转数据相关岗位、想用 Python 处理重复性工作的读者都适合。如果你已经能熟练写爬虫或用 pandas 做分析,这篇对你来说偏基础,可以重点看后面的排查清单和最佳实践部分。接下来,我们直接开工。
1. Python 爬虫与数据分析到底学什么
很多人对 Python 的学习路径有误解,以为要先学完所有语法才能开始做项目。实际上,爬虫和数据分析用到的 Python 知识是高度收敛的。
从实际工作角度看,爬虫需要这几块能力:
- 发送 HTTP 请求:用 requests 库获取网页内容。
- 解析 HTML:用 BeautifulSoup、lxml、re 从网页中提取目标信息。
- 数据存储:把抓到的数据保存为 CSV、Excel、JSON,或写入数据库。
- 应对反爬机制:处理请求头、Cookie、IP 频率限制、验证码等(注意,这里要强调合法授权和遵守 robots 协议)。
数据分析需要这几块能力:
- 数据加载:用 pandas 读取 CSV、Excel、数据库。
- 数据清洗:处理缺失值、重复值、异常值,转换数据类型。
- 数据聚合:groupby、pivot_table 做分组统计。
- 数据可视化:用 matplotlib、seaborn、pyecharts 把结果画成图表。
所以,你真正要掌握的 Python 基础并不复杂:变量与数据类型、列表与字典、条件判断与循环、函数定义、文件读写、异常处理。这些基础内容,配合项目实际操作,几周时间是可以掌握的,用不着花几个月死磕。
下面给出一个完整的路线图,按一周时间安排,每天 2 到 3 小时,可以比较从容地走完。
| 阶段 | 学习内容 | 目标 |
|---|---|---|
| 第 1 天 | Python 环境安装、IDE 配置、基础语法 | 能独立运行脚本,理解变量、数据类型、条件与循环 |
| 第 2 天 | 函数、文件读写、异常处理、常用内置库 | 能写一个带日志和异常捕获的脚本 |
| 第 3 天 | requests 库、HTTP 基础、请求头构造 | 能抓取一个静态页面的 HTML |
| 第 4 天 | BeautifulSoup 解析、CSS 选择器、正则表达式 | 能提取列表页中的标题、链接、价格等信息 |
| 第 5 天 | pandas 数据加载、数据清洗、数据筛选 | 能把爬虫结果保存为 DataFrame 并清洗 |
| 第 6 天 | matplotlib 可视化、分组聚合统计 | 能生成柱状图、折线图、饼图 |
| 第 7 天 | 综合实战:抓取公开数据并分析 | 完成一个“爬虫 + 清洗 + 可视化”闭环 |
这个安排的核心思路是:先建立完整链路,再逐步加深细节。哪怕第一版代码写得很粗糙,也比只学语法不写项目要有效得多。
2. 环境准备与 Python 安装
在开始写代码之前,先把 Python 环境装好。
2.1 Windows 安装步骤
去 Python 官网下载 Windows 安装包。这里有几个关键点:
- 安装时务必勾选 Add Python to PATH,否则命令行里找不到 python 命令。
- 选择 Customize installation,确认 pip 被勾选。
- 安装完成后,打开 CMD 或 PowerShell,执行:
python --version pip --version如果输出版本号,说明安装成功。如果提示“python 不是内部或外部命令”,一般是 PATH 没配好,重新安装并勾选 Add Python to PATH,或者手动把 Python 安装目录加入系统环境变量。
2.2 macOS 安装步骤
macOS 自带 Python 2,但早就停止维护了。建议使用 Homebrew 安装 Python 3:
brew install python3安装完成后验证:
python3 --version pip3 --version注意 macOS 上可能同时存在系统 Python 和 Homebrew Python,建议在项目里使用虚拟环境隔离,避免依赖冲突。
2.3 Linux 安装步骤
Ubuntu / Debian 系使用 apt 安装:
sudo apt update sudo apt install python3 python3-pip -yCentOS / RHEL 系使用 yum 或 dnf:
sudo yum install python3 python3-pip -y2.4 pip 换源与常用命令
国内直连 PyPI 下载依赖经常很慢,建议把 pip 源换成国内镜像。以清华源为例:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple配置完成后,安装依赖的速度会明显提升。常用命令先记住这几个:
pip install 包名 # 安装包 pip uninstall 包名 # 卸载包 pip list # 查看已安装包 pip show 包名 # 查看包详情 pip freeze > requirements.txt # 导出当前环境依赖2.5 开发环境推荐
入门阶段推荐 VS Code,轻量、配置简单、插件生态好。需要装以下插件:
- Python(微软官方插件)
- Pylance(代码补全和类型检查)
- Jupyter(如果要做数据分析,建议直接使用 Notebook)
也可以用 PyCharm Community Edition,社区版免费,对新手更友好,但启动和索引速度比 VS Code 慢一些。
安装完成后,创建一个测试文件 test.py,写入:
print("Hello Python")在终端运行:
python test.py能看到输出就说明整个链路已经通了。
3. Python 基础语法:只学够用的部分
爬虫和数据分析中,Python 基础语法不需要学得面面俱到。下面按优先级列出必须掌握的内容,所有代码都可以直接复制运行。
3.1 变量与数据类型
Python 是动态类型语言,变量不需要声明类型,直接赋值即可。
name = "Python" # 字符串 version = 3.12 # 浮点数 is_ready = True # 布尔值 skills = ["爬虫", "数据分析"] # 列表 info = {"name": "Python", "type": "语言"} # 字典爬虫里最常用的是列表和字典。列表用于存储多个结果,字典用于存储单条记录的字段。比如抓取一条商品信息,用字典比较合适:
item = { "title": "Python编程:从入门到实践", "price": 59.80, "shop": "人民邮电出版社" }3.2 条件判断与循环
条件判断用于过滤数据,比如只保留价格大于 50 的商品;循环用于遍历列表,比如逐个处理每个商品的 URL。
prices = [19.9, 59.8, 45.0, 99.0] for price in prices: if price >= 50: print(f"价格较高:{price}") else: print(f"价格较低:{price}")3.3 函数
函数用于封装重复逻辑。比如写一个发送请求的函数,后续所有爬虫脚本都可以复用:
import requests def fetch_page(url, headers=None, timeout=10): """发送 GET 请求,返回响应对象""" try: response = requests.get(url, headers=headers, timeout=timeout) response.raise_for_status() response.encoding = response.apparent_encoding return response except requests.RequestException as e: print(f"请求失败: {e}") return None3.4 文件读写
爬虫抓到的数据要保存到本地,数据分析前也要从文件读取数据。基础的文件读写:
# 写入文件 with open("output.txt", "w", encoding="utf-8") as f: f.write("Hello Python\n") # 读取文件 with open("output.txt", "r", encoding="utf-8") as f: content = f.read() print(content)注意编码问题:Windows 下默认编码可能不是 UTF-8,建议读写文件时都显式指定encoding="utf-8"。
3.5 异常处理
爬虫运行中常见网络超时、连接拒绝、解析失败等问题。用 try-except 包裹可能出错的代码,是保证脚本稳定运行的关键:
try: result = 10 / 0 except ZeroDivisionError as e: print(f"捕获异常: {e}") finally: print("无论如何都会执行")Python 基础学到这个程度,已经足够支撑你进入爬虫和数据分析的项目实践了。不要在这里恋战,先写项目,遇到不懂的语法再回头查,效果更好。
4. 爬虫入门:requests 请求库实战
爬虫的第一步是拿到网页内容。requests 是 Python 最常用的 HTTP 请求库,接口设计简洁,上手成本很低。
4.1 安装 requests
pip install requests4.2 发送 GET 请求
以请求一个公开的测试页面为例:
import requests url = "https://httpbin.org/get" response = requests.get(url, timeout=10) print(response.status_code) # 状态码 print(response.text[:500]) # 响应内容前500字符运行后你会看到类似这样的输出:
200 { "args": {}, "headers": { "Accept": "*/*", "Host": "httpbin.org", "User-Agent": "python-requests/2.31.0" }, "origin": "你的IP地址", "url": "https://httpbin.org/get" }如果返回 200,说明请求成功。如果返回 403 或 418,说明目标服务器有反爬策略,需要构造请求头。
4.3 构造请求头
很多网站会检查 User-Agent,默认的python-requests很容易被识别。构造一个浏览器常见的请求头:
import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept-Language": "zh-CN,zh;q=0.9" } url = "https://httpbin.org/get" response = requests.get(url, headers=headers, timeout=10) print(response.json()["headers"]["User-Agent"])从返回结果可以看到,服务器收到的 User-Agent 已经变成了浏览器的标识。
4.4 处理 Cookie 与 Session
如果需要保持登录状态,建议使用 requests.Session。Session 会保存 Cookie 信息,后续请求自动携带:
import requests session = requests.Session() # 第一次请求,服务器设置 Cookie session.get("https://httpbin.org/cookies/set?name=python") # 第二次请求,自动携带 Cookie response = session.get("https://httpbin.org/cookies") print(response.text)注意:使用 Session 抓取需要登录的数据时,要确保你有权限访问这些数据,不要绕过登录逻辑抓取非公开信息。
4.5 请求频率控制
批量抓取时,请求过快容易触发反爬机制,也会给目标服务器造成压力。建议每次请求之间加延时:
import time import requests urls = ["https://httpbin.org/get"] * 5 headers = {"User-Agent": "Mozilla/5.0"} for i, url in enumerate(urls): response = requests.get(url, headers=headers, timeout=10) print(f"第 {i+1} 次请求完成,状态码: {response.status_code}") time.sleep(1) # 每次请求间隔1秒这是爬虫的基本礼仪,也是降低被封风险的有效手段。更严格的频率限制、代理池、验证码处理、滑块等反爬问题,属于进阶内容,需要结合具体网站和合规要求来处理,这里不展开。
5. HTML 解析:BeautifulSoup 从页面提取数据
拿到 HTML 之后,下一步是提取目标信息。BeautifulSoup 是最常用的解析库,配合 lxml 解析器效率更高。
5.1 安装 BeautifulSoup 和 lxml
pip install beautifulsoup4 lxml5.2 基础解析流程
from bs4 import BeautifulSoup html = """ <html> <body> <div class="item">import csv import requests from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } url = "https://books.toscrape.com/" response = requests.get(url, headers=headers, timeout=10) if response.status_code == 200: response.encoding = "utf-8" soup = BeautifulSoup(response.text, "lxml") books = [] for article in soup.select("article.product_pod"): title = article.select_one("h3 a").get("title") price = article.select_one("p.price_color").text books.append({"title": title, "price": price}) print(f"抓取到 {len(books)} 本图书") with open("books.csv", "w", encoding="utf-8", newline="") as f: writer = csv.DictWriter(f, fieldnames=["title", "price"]) writer.writeheader() writer.writerows(books) print("数据已保存到 books.csv") else: print(f"请求失败,状态码: {response.status_code}")books.toscrape.com 是一个专门用于爬虫练习的公开网站,数据抓取权限清晰,适合入门测试。实际抓取其他网站时,要先检查 robots.txt 和网站使用条款,确认有权限抓取。
5.4 翻页抓取
列表页通常有多页,翻页抓取的核心是找到 URL 规律。很多网站的翻页 URL 规则是?page=2、?page=3:
import time import requests from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } all_books = [] for page in range(1, 4): url = f"https://books.toscrape.com/catalogue/page-{page}.html" response = requests.get(url, headers=headers, timeout=10) if response.status_code != 200: print(f"第 {page} 页请求失败") continue soup = BeautifulSoup(response.text, "lxml") for article in soup.select("article.product_pod"): title = article.select_one("h3 a").get("title") price = article.select_one("p.price_color").text all_books.append({"title": title, "price": price}) print(f"第 {page} 页完成,当前累计 {len(all_books)} 条") time.sleep(1) print(f"全部完成,共 {len(all_books)} 条数据")这个示例演示了批量任务的雏形:循环请求、逐步解析、统一保存。后面可以扩展到更大的数据集。
6. pandas 数据清洗与分析
爬虫抓回来的数据往往是脏的,比如价格里有货币符号、日期格式不统一、存在缺失值。这些都需要用 pandas 来处理。
6.1 安装 pandas
pip install pandas6.2 读取 CSV 数据
用上一节的 books.csv 为例:
import pandas as pd df = pd.read_csv("books.csv") print(df.head()) print(df.info())head()显示前 5 行,info()显示每列的数据类型和非空数量。
6.3 数据清洗:去除货币符号并转换类型
价格列是£51.77这样的格式,需要去掉货币符号并转为浮点数:
import pandas as pd df = pd.read_csv("books.csv") # 去掉货币符号,转为浮点数 df["price"] = df["price"].str.replace("£", "").astype(float) print(df.dtypes) print(df["price"].describe())describe()会输出价格列的统计信息:平均值、标准差、最小值、最大值等。到这里,数据已经可以进行基础分析了。
6.4 处理缺失值和重复值
真实数据中,缺失值和重复值非常常见:
import pandas as pd # 示例数据 data = { "title": ["A", "B", "C", "A"], "price": [10.5, None, 30.2, 10.5] } df = pd.DataFrame(data) # 查看缺失值 print(df.isnull().sum()) # 删除包含缺失值的行 df_clean = df.dropna() # 删除重复行 df_clean = df_clean.drop_duplicates() print(df_clean)对于缺失值,除了直接删除,还可以用均值、中位数或前向填充来处理。具体用哪种方式取决于业务场景:
# 用均值填充 df["price"] = df["price"].fillna(df["price"].mean()) # 用中位数填充 df["price"] = df["price"].fillna(df["price"].median())6.5 数据筛选与排序
import pandas as pd df = pd.read_csv("books.csv") df["price"] = df["price"].str.replace("£", "").astype(float) # 筛选价格大于 30 的图书 expensive_books = df[df["price"] > 30] print(expensive_books) # 按价格排序 sorted_books = df.sort_values("price", ascending=False) print(sorted_books.head(5))6.6 分组统计
如果你的数据中有一个分类列(比如图书类别、商品分类),可以按类别做分组统计:
import pandas as pd data = { "category": ["编程", "编程", "数据", "数据", "数据"], "price": [59.8, 79.0, 89.0, 45.0, 120.0] } df = pd.DataFrame(data) # 按分类统计数量和平均价格 result = df.groupby("category").agg( count=("price", "count"), avg_price=("price", "mean") ) print(result)输出:
count avg_price category 编程 2 69.4 数据 3 84.7这就是数据分析中非常高频的操作。实际工作中,你还会用到pivot_table、merge、concat等操作,核心逻辑都是类似的:先加载数据,再清洗,再聚合。
7. matplotlib 数据可视化
数据清洗完成后,用图表展示结果会更直观。matplotlib 是 Python 最基础的可视化库。
7.1 安装 matplotlib
pip install matplotlib7.2 绘制折线图和柱状图
import matplotlib.pyplot as plt import pandas as pd # 准备数据 data = { "month": ["1月", "2月", "3月", "4月", "5月", "6月"], "sales": [120, 150, 130, 180, 160, 210] } df = pd.DataFrame(data) # 折线图 plt.figure(figsize=(8, 5)) plt.plot(df["month"], df["sales"], marker="o", linestyle="-") plt.title("月度销售额趋势") plt.xlabel("月份") plt.ylabel("销售额(万元)") plt.grid(True, alpha=0.3) plt.show() # 柱状图 plt.figure(figsize=(8, 5)) plt.bar(df["month"], df["sales"], color="skyblue") plt.title("月度销售额对比") plt.xlabel("月份") plt.ylabel("销售额(万元)") plt.show()7.3 中文显示问题
matplotlib 默认字体不支持中文,图表中会出现方框。解决方式是手动指定中文字体:
import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "PingFang SC"] plt.rcParams["axes.unicode_minus"] = False不同系统对应的字体名称不同。Windows 下用SimHei或Microsoft YaHei,macOS 下可以用PingFang SC,Linux 下需要先安装中文字体。
7.4 画布保存
写完图表,直接显示之外,建议保存为图片文件,便于后续使用:
plt.savefig("sales.png", dpi=150, bbox_inches="tight")dpi控制清晰度,bbox_inches="tight"会自动裁剪多余空白。
8. 综合实战:从抓取到分析的全流程
到这里,我们把爬虫、数据清洗、可视化串成一条完整链路。用一个实际场景来演示:抓取公开图书网站的图书信息,清洗价格数据,统计价格分布,并生成直方图。
8.1 抓取数据
import requests from bs4 import BeautifulSoup import pandas as pd headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } url = "https://books.toscrape.com/" response = requests.get(url, headers=headers, timeout=10) soup = BeautifulSoup(response.text, "lxml") books = [] for article in soup.select("article.product_pod"): title = article.select_one("h3 a").get("title") price = article.select_one("p.price_color").text books.append({"title": title, "price": price}) df = pd.DataFrame(books) print(f"抓取到 {len(df)} 条数据")8.2 清洗数据
# 清洗价格列 df["price"] = df["price"].str.replace("£", "").astype(float) # 检查缺失值 print(df.isnull().sum()) print(df.head())8.3 分析价格分布
import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "PingFang SC"] plt.rcParams["axes.unicode_minus"] = False # 直方图 plt.figure(figsize=(10, 6)) plt.hist(df["price"], bins=10, edgecolor="black", alpha=0.7) plt.title("图书价格分布") plt.xlabel("价格(英镑)") plt.ylabel("数量") plt.grid(True, alpha=0.3) plt.show() # 输出统计信息 print(df["price"].describe())运行结果会显示价格均值、中位数、最大最小值,以及一张价格分布直方图。到这里,你已经完成了一个爬虫 + 数据分析 + 可视化的最小闭环。这个流程扩展一下,完全可以应用到商品比价、舆情分析、市场调研等场景。
9. 常见问题与排查方法
以下是 Python 学习和实践中最常见的报错与问题,直接对照排查。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
pip 不是内部或外部命令 | 安装时没有勾选 Add Python to PATH | 检查环境变量 | 重新安装并勾选,或手动添加 PATH |
ModuleNotFoundError: No module named 'requests' | 依赖未安装 | 执行pip list查看 | 执行pip install requests |
| 安装依赖速度极慢 | 默认连接 PyPI 官方源 | 观察下载进度 | 配置国内镜像源 |
| 运行脚本中文乱码 | 文件编码不是 UTF-8 | 检查文件编码 | 在文件开头添加# -*- coding: utf-8 -*- |
| 爬虫请求返回 403 | 请求头被服务器识别 | 查看响应内容 | 构造浏览器 User-Agent,添加 Cookie |
| 爬虫请求超时 | 网络问题或目标服务器响应慢 | 检查网络连接 | 增加 timeout,设置重试机制 |
| BeautifulSoup 解析不到内容 | 选择器写错或页面是动态渲染 | 打印 HTML 检查结构 | 审查选择器,动态内容用 Selenium 或找接口 |
| pandas 读取 CSV 乱码 | 文件编码与读取编码不一致 | 查看原文件编码 | 指定encoding="utf-8"或encoding="gbk" |
| matplotlib 中文显示为方块 | 默认字体不支持中文 | 打印可用字体列表 | 设置font.sans-serif为中文字体 |
ValueError: could not convert string to float | 字符串中包含非数字字符 | 打印原始值 | 用str.replace清理符号后再转换 |
10. 学习建议与避坑指南
最后给几条实操建议,这些是最容易踩坑的地方。
10.1 不要先刷完所有语法再做项目
Python 的语法工具是“够用就行”的。你只需要掌握变量、列表、字典、循环、判断、函数、文件读写和异常处理,就可以开始写爬虫。其余语法在项目中遇到时再查即可。先把“爬虫到分析”的闭环跑通,再逐步补充细节,节奏更健康。
10.2 用虚拟环境隔离项目依赖
不同项目可能依赖不同版本的库,直接全部装到全局环境容易冲突。建议每个项目创建独立虚拟环境:
python -m venv venv激活虚拟环境:
Windows:
venv\Scripts\activatemacOS / Linux:
source venv/bin/activate之后再执行 pip install,依赖只会安装到当前虚拟环境里,不会污染全局。
10.3 爬虫必须注意合规性
抓取数据前,先检查目标网站的 robots.txt,确认允许抓取的范围。只抓取公开、合法授权的数据,不抓取需要登录才能访问的非公开信息,不绕过验证码、不放大请求频率。如果数据是用于商业用途,务必确认目标网站的使用条款和版权要求。批量请求要控制频率,避免对目标服务器造成压力。
10.4 建立自己的代码库
把常用的功能写成函数,分模块保存。比如 requests 请求函数、CSV 保存函数、数据清洗函数,放到独立的.py文件里。下次做新项目时直接导入,不用重新写:
# utils.py import requests def fetch_page(url, headers=None, timeout=10): try: response = requests.get(url, headers=headers, timeout=timeout) response.raise_for_status() response.encoding = response.apparent_encoding return response except requests.RequestException: return None调用时:
from utils import fetch_page response = fetch_page("https://books.toscrape.com/", headers={"User-Agent": "Mozilla/5.0"}) if response: print(response.status_code)这是一套比较轻的“工具箱”思路,随着实践增加逐步扩充,你的开发效率会有明显提升。
10.5 先小批量验证,再全量运行
无论是爬虫还是数据清洗,第一次运行时先用小批量数据验证流程,确认输出正确后再放大规模。批量抓取时,建议打印进度日志,方便定位失败位置:
for i, url in enumerate(urls): print(f"[{i+1}/{len(urls)}] 正在处理: {url}")这样跑挂了,你能立刻知道是在哪一步出的问题。遇到失败请求,可以用 try-except 捕获并记录到日志文件,重试策略放到日志清晰之后再设计。
11. 总结与下一步
从环境配置、基础语法、requests 请求、BeautifulSoup 解析、pandas 清洗,到 matplotlib 可视化,这条路已经完整走了一遍。最值得你记住的是:Python 学习要以项目为主线,不要孤立地学语法。爬虫和数据分析是很好的入门方向,因为两者结合能让你快速看到“从网上拿数据到出分析结果”的完整效果,正反馈很强。
下一步建议做这三件事:
- 把文章里的代码全部手动敲一遍,不要复制粘贴。敲的过程会暴露语法细节,比如缩进、冒号、引号,这些都是只看不写容易忽略的。
- 找一个你熟悉的公开网站(非登录、非敏感信息),尝试自己写一个抓取脚本,用 pandas 做一次简单统计。
- 把数据可视化中常用的图表类型(折线图、柱状图、饼图、直方图)都画一遍,理解不同图表适合表达什么信息。
爬虫这个方向,从静态页面到动态渲染、从单页到分布式、从请求到反爬对抗,越往后越深;数据分析方向,从 pandas 到 numpy、从描述统计到建模预测,也能不断延伸。但所有进阶能力,都建立在“能把一个完整的小项目跑通”这个基础上。先完成最小闭环,再决定往哪个方向深入,这套方法对大多数零基础学习者来说,是更不容易放弃的路线。