Python爬虫与数据分析学习路线:从零基础到完整项目实战

Python爬虫与数据分析学习路线:从零基础到完整项目实战 先问自己一个问题网上 Python 教程这么多为什么很多人还是学完就忘、遇到项目就懵原因往往不是不够努力而是学习路径太散。今天看两节基础语法明天跳去学爬虫后天又听说数据分析很火结果每样都只碰了皮毛。如果有一套从零开始、覆盖爬虫与数据分析两条主流就业方向的学习主线情况会好很多。本文就围绕“Python 基础语法 爬虫开发 数据分析”这条完整学习路线整理一份系统化实操教程从环境搭建开始到写出第一个 Python 程序再到爬取真实网页数据、完成数据清洗与可视化分析每个环节都给出可复制的代码和避坑说明。这篇文章适合四类读者完全零基础想系统学 Python 但不知道从哪下手。学过 Python 基础但不会用 requests、pandas 做实际项目。想转行数据分析或爬虫方向的开发者需要一份完整项目练手。已经在网上收藏了不少教程但缺少一条清晰主线的同学。学完本文后你将掌握一套完整的入门到进阶链路Python 环境搭建、核心语法、requests 爬虫、BeautifulSoup 解析、pandas 数据清洗、matplotlib 数据可视化并且能把它们串成一个真实项目。1. 为什么用“爬虫 数据分析”作为 Python 学习主线1.1 Python 到底能做什么Python 是一门解释型、面向对象的通用编程语言语法简洁第三方库丰富。日常开发中它比较常见的应用方向包括Web 开发Django、Flask、FastAPI。爬虫开发requests、Scrapy、Selenium。数据分析pandas、NumPy、matplotlib。人工智能TensorFlow、PyTorch。自动化运维与测试Ansible、pytest。办公自动化openpyxl、python-docx。对于零基础学习者来说最容易在短期内获得成就感的方向就是爬虫与数据分析。因为这两个方向正反馈很强爬虫可以很快看到“从网上拿到数据”的结果数据分析可以让一堆杂乱数字变成直观图表。更重要的是这两条路线需要的 Python 核心语法高度重合学一遍基础可以同时服务两个方向。1.2 爬虫与数据分析的关系有人会把爬虫和数据分析看成两件独立的事实际工程中它们经常是一条流水线网页抓取 - 数据解析 - 数据清洗 - 数据存储 - 数据分析 - 可视化展示爬虫解决的是“数据从哪里来”的问题数据分析解决的是“数据有什么价值”的问题。只学爬虫你拿到的原始数据可能充满重复、缺失和格式问题只学数据分析你手上没有足够量级的真实数据练习效果会大打折扣。把两者结合在一起学习正好形成闭环。1.3 常见爬虫类型与工作场景爬虫按实现方式和策略可以分为几个常见类型类型特点典型场景通用爬虫从起始 URL 出发遍历整个网站或全网搜索引擎抓取网页批量型爬虫按固定规则批量抓取页面数据采集商品信息、文章列表增量型爬虫只抓取新增或更新的数据监控价格波动、新闻更新垂直型爬虫只针对特定领域或特定网站抓取招聘信息、房产信息初学者通常从批量型爬虫入手也就是写一个脚本循环请求多个网页解析并保存结果。本文实战部分会以这种类型为例。1.4 为什么要强调“学完即可用”“学完即可就业”听起来像口号但拆开看入门级 Python 爬虫或数据分析岗位需要的能力其实很具体熟练使用 Python 基础语法能写清晰的脚本。会使用 requests 请求网页能处理常见的反爬机制。会使用 pandas 做数据清洗和统计分析。会使用 matplotlib 或 pyecharts 画图。能独立完成一个“从抓取到分析”的小项目。这些能力不需要掌握 Python 的全部特性而是要求把常用部分练熟。这也是本文采用主线式学习法的原因不追求面面俱到而是围绕“爬虫 数据分析”这条路径把必用的知识点逐个击破。2. Python 环境准备与工具选择2.1 Python 版本选择目前 Python 3 是绝对主流官方已经停止对 Python 2 的维护。具体版本上建议安装最新的稳定版 Python 3例如 3.10 或更高版本。版本不需要强求最新但不要低于 3.8否则部分第三方库可能不支持。如果你在安装时不确定选哪个版本记住一条原则Windows 用户去 Python 官网下载安装包安装时勾选 Add Python to PATH。macOS 用户可以使用 Homebrew 安装brew install python3。Linux 用户一般自带 Python 3可以用 python3 --version 检查。需要特别提醒的是不同操作系统下 Python 命令可能不同。Windows 有时要输入 pymacOS 和 Linux 输入 python3。2.2 IDE 与编辑器推荐初学者不要一开始就折腾复杂的 IDE选择一个开箱即用的环境更重要。VS Code轻量插件丰富适合写脚本和调试需要自己配置 Python 插件。PyCharm专业 Python IDE社区版免费有代码提示、调试器和数据库工具。Jupyter Notebook适合数据分析场景可以分单元格运行代码方便查看中间结果。本文中的基础语法和爬虫实例用 VS Code 或 PyCharm 都可以运行数据分析实例用 Jupyter Notebook 体验会更好。如果你已经安装了 Anaconda那么 Jupyter 和 pandas、matplotlib 都已经内置不需要额外安装。2.3 创建虚拟环境虚拟环境是 Python 项目开发中最值得养成的习惯之一。它可以让每个项目的第三方库互相隔离避免版本冲突。新建项目目录后在终端执行mkdir python_learning cd python_learning python -m venv venv启动虚拟环境Windows PowerShellvenv\Scripts\activatemacOS / Linuxsource venv/bin/activate激活后终端左侧通常会出现 (venv) 标记。接下来的所有包安装都建议在虚拟环境内完成。2.4 安装核心依赖本文需要安装的第三方库有pip install requests beautifulsoup4 pandas matplotlib安装完成后可以用下面的命令检查版本pip list如果下载速度较慢可以临时使用国内镜像源pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple版本需要根据你的项目实际情况调整本文示例以常见稳定环境为例重点演示编程思路不绑定某个具体版本号。3. Python 基础语法精讲从变量到函数3.1 变量与基本数据类型Python 是动态类型语言定义变量不需要声明类型直接赋值即可。# 文件路径demo_basic.py name 小明 # 字符串 age 20 # 整数 height 1.75 # 浮点数 is_student True # 布尔值 print(name, age, height, is_student) print(type(age))运行结果小明 20 1.75 True class int代码中 type() 用于查看变量类型。Python 常见的内置类型包括 int、float、str、bool、list、tuple、dict、set后面几个属于容器类型在爬虫和数据分析中非常常用。3.2 字符串与列表操作字符串和列表是最常用的两类数据容器。# 字符串操作 text hello python print(text.upper()) # 转大写 print(text.split( )) # 按空格切割 # 列表操作 fruits [apple, banana, cherry] fruits.append(orange) # 追加元素 print(fruits) print(fruits[0]) # 通过下标访问第一个元素 print(len(fruits)) # 列表长度 # 列表推导式 numbers [i * 2 for i in range(5)] print(numbers)列表推导式是 Python 中非常推荐的写法它能把 for 循环和列表生成合并成一行。爬虫解析和数据分析中经常用它批量处理数据。3.3 流程控制条件与循环# 条件判断 score 85 if score 90: print(优秀) elif score 60: print(及格) else: print(不及格) # for 循环遍历列表 for fruit in fruits: print(f当前水果: {fruit}) # while 循环 count 0 while count 3: print(f第 {count 1} 次) count 1注意 f-string 是 Python 3.6 以后推荐的字符串格式化方式它在爬虫拼接 URL 和数据分析打印结果时非常方便。3.4 函数让代码可重复使用函数是组织代码的基础单位。写爬虫时请求一个网页、解析一条数据、保存一份文件都应该拆成独立函数。def get_area(radius): 计算圆的面积 pi 3.14159 return pi * radius ** 2 def get_rectangle_area(width, height): return width * height print(get_area(5)) print(get_rectangle_area(4, 6))函数参数还可以设置默认值这在爬虫中很常见比如设置默认请求头、默认超时时间def fetch_page(url, timeout10): print(f请求地址: {url}, 超时时间: {timeout}秒) # 实际请求逻辑略 return None3.5 文件读写爬虫抓到的数据最终需要保存到文件或数据库。文件读写是最基础的能力。# 写入文件 with open(data.txt, w, encodingutf-8) as f: f.write(第一条数据\n) f.write(第二条数据\n) # 读取文件 with open(data.txt, r, encodingutf-8) as f: content f.read() print(content)这里使用 with 关键字管理文件资源即使出错也能自动关闭文件。encodingutf-8 是为了避免中文乱码爬虫场景下非常关键。3.6 异常处理爬虫请求网络时会遇到超时、连接失败、页面结构变更等问题。如果没有异常处理脚本会在第一处报错就中断。try: number int(abc) except ValueError as e: print(转换失败:, e) except Exception as e: print(未知异常:, e) else: print(没有异常时执行) finally: print(无论是否异常都执行)处理异常时建议先捕获具体异常类型再用 Exception 兜底不要一开始就写空 except。4. requests 爬虫实战抓取网页数据4.1 requests 库核心用法requests 是 Python 中最流行的 HTTP 请求库用起来非常简单。import requests url https://httpbin.org/get response requests.get(url, timeout10) print(状态码:, response.status_code) print(响应内容类型:, response.headers.get(Content-Type)) print(网页内容前200个字符:) print(response.text[:200])参数说明status_codeHTTP 状态码200 表示成功404 表示页面不存在403 表示禁止访问。timeout请求超时时间单位秒强烈建议设置否则可能一直等待。response.text以文本形式返回响应内容适用于 HTML、JSON 等。4.2 带请求头和参数的请求很多网站会检查 User-Agent 字段用于识别请求是否来自浏览器。如果不设置有些服务器会直接拒绝响应。import requests headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0 Safari/537.36, Accept-Language: zh-CN,zh;q0.9 } params { keyword: python, page: 1 } url https://httpbin.org/get response requests.get(url, headersheaders, paramsparams, timeout10) # 返回的是 JSON可以直接用 .json() 解析 data response.json() print(请求参数回显:, data.get(args)) print(请求头中的User-Agent:, data.get(headers, {}).get(User-Agent))params 参数会被 requests 自动拼接到 URL 上相当于把字典转换成 ?keywordpythonpage1 的查询字符串。4.3 用 BeautifulSoup 解析 HTMLrequests 拿到的是 HTML 源码需要解析后才能提取目标数据。BeautifulSoup 是最友好的 HTML 解析库之一。from bs4 import BeautifulSoup html ul li classitemPython 从入门到实践/li li classitem hotPython 爬虫开发/li li classitemPython 数据分析/li /ul soup BeautifulSoup(html, html.parser) # 提取所有 li 标签 items soup.find_all(li) for item in items: print(标题:, item.text) print(class属性:, item.get(class))BeautifulSoup 的常用方法find(name, attrs)查找第一个匹配标签。find_all(name, attrs)查找所有匹配标签返回列表。select(css_selector)使用 CSS 选择器。get_text() 或 text获取标签内的文本。get(attr_name)获取标签属性值。实际写爬虫时优先用 .select() 配合 CSS 选择器代码更简洁items soup.select(li.item) for item in items: print(item.text)4.4 完整爬虫案例抓取名言列表下面我们完成一个完整的爬虫项目目标页面使用 quotes.toscrape.com这是一个专门用来练习爬虫的网站没有复杂反爬适合初学者。创建一个爬虫脚本文件# 文件路径spider_quotes.py import requests from bs4 import BeautifulSoup def fetch_page(url): 请求网页并返回 BeautifulSoup 对象 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } response requests.get(url, headersheaders, timeout10) response.encoding utf-8 if response.status_code 200: return BeautifulSoup(response.text, html.parser) return None def parse_quotes(soup): 从 BeautifulSoup 对象中提取名言、作者、标签 quotes [] items soup.select(div.quote) for item in items: text item.select_one(span.text).get_text() author item.select_one(small.author).get_text() tags [tag.get_text() for tag in item.select(a.tag)] quotes.append({ 名言: text, 作者: author, 标签: , .join(tags) }) return quotes def save_to_csv(quotes, filenamequotes.csv): 将数据保存为 CSV 文件 import csv with open(filename, w, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnames[名言, 作者, 标签]) writer.writeheader() writer.writerows(quotes) def main(): url https://quotes.toscrape.com/ soup fetch_page(url) if soup is None: print(页面请求失败) return quotes parse_quotes(soup) save_to_csv(quotes) print(f成功抓取 {len(quotes)} 条名言已保存到 quotes.csv) if __name__ __main__: main()运行脚本python spider_quotes.py预期输出成功抓取 10 条名言已保存到 quotes.csv4.5 爬虫结果中英文编码问题处理CSV 文件如果用 Excel 打开出现中文乱码通常是因为没有使用 utf-8-sig 编码。utf-8-sig 会在文件开头加入 BOMByte Order Mark标记Excel 识别后就能正确显示中文。保存 CSV 时标准写法是with open(filename, w, encodingutf-8-sig, newline) as f:这个细节在菜鸟阶段很容易忽略但实际项目里经常遇到。4.6 爬虫法律边界与注意事项爬虫虽然有趣但必须在合法合规的前提下进行。这里强调几条基本底线遵守目标网站的 robots.txt 协议查看网站是否允许爬取。控制请求频率不要给目标服务器造成压力。不抓取涉及个人隐私、账号密码、支付信息的数据。抓取的数据仅用于学习研究不用于商业用途。在测试环境练习时优先使用 quotes.toscrape.com 这类专门为爬虫学习设计的网站。5. pandas 数据分析实战清洗与统计5.1 pandas 核心数据结构Series 和 DataFramepandas 是 Python 数据分析的核心库它的两个核心数据结构是 Series 和 DataFrame。Series一维数据类似带索引的数组。DataFrame二维表格数据类似 Excel 表格。import pandas as pd # 创建 Series s pd.Series([1, 2, 3, 4]) print(Series:) print(s) # 创建 DataFrame data { 姓名: [小明, 小红, 小刚], 年龄: [20, 22, 21], 城市: [北京, 上海, 广州] } df pd.DataFrame(data) print(\nDataFrame:) print(df)运行结果Series: 0 1 1 2 2 3 3 4 dtype: int64 DataFrame: 姓名 年龄 城市 0 小明 20 北京 1 小红 22 上海 2 小刚 21 广州5.2 读取 CSV 文件并查看数据上一节爬虫保存的 quotes.csv 可以直接用 pandas 读取。import pandas as pd df pd.read_csv(quotes.csv) # 查看前5行 print(df.head()) # 查看数据基本信息 print(df.info()) # 查看列名 print(df.columns.tolist()) # 统计描述 print(df.describe())head() 默认显示前 5 行info() 可以查看每列的数据类型和非空数量是数据分析前最常执行的两个操作。5.3 数据清洗处理缺失值与重复值真实爬虫抓下来的数据往往有缺失、重复、格式不一致等问题。数据清洗是数据分析中最耗时的环节。import pandas as pd # 构造一个有问题的数据集 data { 姓名: [小明, 小红, 小刚, 小明, None], 年龄: [20, None, 21, 20, 22], 城市: [北京, 上海, 广州, 北京, 深圳] } df pd.DataFrame(data) print(原始数据:) print(df) # 查看缺失值情况 print(\n缺失值统计:) print(df.isnull().sum()) # 删除包含缺失值的行 df_cleaned df.dropna() print(\n删除缺失值后:) print(df_cleaned) # 删除重复行 df_deduplicated df.drop_duplicates() print(\n删除重复行后:) print(df_deduplicated) # 填充缺失值 df_filled df.fillna({年龄: 0, 姓名: 未知}) print(\n填充缺失值后:) print(df_filled)常用清洗方法dropna()删除包含空值的行或列。fillna()用指定值填充空值。drop_duplicates()删除重复行。rename()重命名列名。astype()转换数据类型。5.4 数据分组与统计如果抓取了大量名言数据我们可以按作者或标签做分组统计得到最有价值的作者。import pandas as pd df pd.read_csv(quotes.csv) # 按作者分组统计名言数量 author_counts df[作者].value_counts() print(各作者名言数量:) print(author_counts.head(10)) # 按标签统计 tag_counts df[标签].value_counts() print(\n各标签数量:) print(tag_counts.head(10))value_counts() 是数据分析中出现频率最高的方法之一用于统计某列各类别的频数。5.5 多页爬虫获取更多数据用于分析为了让分析更有意义我们可以把前面爬虫扩展为多页抓取。quotes.toscrape.com 的分页 URL 格式非常规律第二页是 https://quotes.toscrape.com/page/2/第三页是 /page/3/以此类推。# 文件路径spider_quotes_pages.py import csv import time import requests from bs4 import BeautifulSoup def fetch_page(url): headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } response requests.get(url, headersheaders, timeout10) response.encoding utf-8 if response.status_code 200: return BeautifulSoup(response.text, html.parser) return None def parse_quotes(soup): quotes [] items soup.select(div.quote) for item in items: text item.select_one(span.text).get_text() author item.select_one(small.author).get_text() tags [tag.get_text() for tag in item.select(a.tag)] quotes.append({ 名言: text, 作者: author, 标签: , .join(tags) }) return quotes def main(): all_quotes [] for page in range(1, 11): # 抓取前10页 url fhttps://quotes.toscrape.com/page/{page}/ print(f正在抓取: {url}) soup fetch_page(url) if soup is None: break quotes parse_quotes(soup) if not quotes: break all_quotes.extend(quotes) time.sleep(1) # 控制请求频率避免给服务器压力 with open(quotes_all.csv, w, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnames[名言, 作者, 标签]) writer.writeheader() writer.writerows(all_quotes) print(f抓取完成共 {len(all_quotes)} 条名言) if __name__ __main__: main()time.sleep(1) 表示每次请求后间隔 1 秒这是编写爬虫时需要养成的习惯可以降低对目标服务器的压力也能减少被反爬机制拦截的概率。6. matplotlib 数据可视化把结果画出来6.1 最简单的折线图分析完成后图表是表达结果最直观的方式。matplotlib 是 Python 最基础的可视化库。import matplotlib.pyplot as plt # 准备数据 x [1, 2, 3, 4, 5] y [2, 4, 1, 5, 3] # 画折线图 plt.plot(x, y, markero) plt.title(示例折线图) plt.xlabel(X 轴) plt.ylabel(Y 轴) plt.grid(True) plt.show()6.2 柱状图展示作者名言数量将第 5 节的统计结果用柱状图展示import pandas as pd import matplotlib.pyplot as plt # 设置中文字体防止标题乱码 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False df pd.read_csv(quotes_all.csv) # 统计数据 author_counts df[作者].value_counts().head(10) # 画柱状图 plt.figure(figsize(10, 6)) author_counts.plot(kindbar, colorskyblue) plt.title(名言数量最多的前10位作者) plt.xlabel(作者) plt.ylabel(名言数量) plt.xticks(rotation45) plt.tight_layout() plt.savefig(author_bar.png, dpi150) plt.show()注意 plt.rcParams 中的字体设置。不同操作系统显示中文的方法不一样Windows 可以用 SimHeimacOS 可以用 Arial Unicode MSLinux 需要安装中文字体。如果图表标题出现方框通常是字体问题。6.3 饼图展示标签占比import pandas as pd import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False df pd.read_csv(quotes_all.csv) # 把标签列拆开统计 tag_series df[标签].str.split(, ).explode() tag_counts tag_series.value_counts().head(8) plt.figure(figsize(8, 8)) tag_counts.plot(kindpie, autopct%1.1f%%) plt.title(名言标签分布) plt.ylabel() plt.tight_layout() plt.show()split(, ).explode() 是 pandas 中把一行拆成多行的小技巧先把标签字符串拆成列表再用 explode 展开最后统计每个标签出现的次数。7. 常见问题与排查思路7.1 问题清单问题现象常见原因解决思路安装包时提示 pip 不是内部或外部命令Python 未加入 PATH重新安装 Python勾选 Add Python to PATHrequests 请求超时网络不稳定或目标网站响应慢设置 timeout并在异常处理中重试网页返回 CSV 文件乱码编码格式不对读取时指定 encoding保存时使用 utf-8-sigBeautifulSoup 找不到元素页面结构变化或 JS 动态加载先打印 HTML 检查结构必要时换 Seleniumpandas 读取 CSV 时列名变成 UnnamedCSV 中有空列使用 index_col0 或清洗列名matplotlib 中文显示方框系统缺少中文字体设置 rcParams 的 font.sans-serif 为已安装字体7.2 爬虫请求失败的排查清单当爬虫请求失败时按以下顺序排查用浏览器打开同样的 URL确认页面能正常访问。检查返回的状态码403 通常是反爬404 是 URL 写错500 是服务器问题。检查请求头是否完整至少包含 User-Agent。检查请求频率是否过高尝试增加 sleep 间隔。如果页面内容是 JS 动态加载的requests 拿不到目标数据需要改用 Selenium。7.3 数据分析结果的准确性检查分析结果不合理时先检查数据质量数据是否完整有没有大量 NaN。是否有重复行导致统计偏大。列的类型是否正确例如年龄列被当成字符串。标签列是否有多值混在一个单元格里。常见做法是先用 head()、info()、describe() 快速预览数据弄清楚结构后再做统计。8. 最佳实践与工程建议8.1 爬虫工程化规范所有请求函数都要设置 timeout避免卡死。请求头统一抽取为常量或配置文件避免在每个函数里重复写。使用 time.sleep 或自定义限速逻辑控制请求频率。把 URL、选择器、保存路径等配置与代码逻辑分离。对抓取结果做编码统一保存时使用 utf-8-sig。写日志而不是无脑 print方便定位问题。一个简单的日志示例import logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s ) logging.info(开始抓取页面) logging.error(请求失败)8.2 数据分析流程规范拿到数据后先做探查性分析不要急着建模或统计。清洗前先备份原始数据。每一步清洗操作尽量生成新的 DataFrame而不是在原数据上反复修改。对常用操作封装成函数方便复用。图表标题、轴标签、图例都要写清楚。结果输出时不仅给图表还要解释图表反映了什么趋势。8.3 学习路线建议如果你想系统掌握这条链路可以按以下阶段推进阶段一Python 基础语法。重点掌握变量、字符串、列表、字典、条件、循环、函数、文件读写。阶段二爬虫入门。重点掌握 requests 和 BeautifulSoup多写几个单页爬虫再扩展到多页抓取。阶段三数据分析入门。重点掌握 pandas 的 DataFrame 读取、清洗、分组、聚合配合 matplotlib 可视化。阶段四综合项目。做一个“爬取一整类数据 → 清洗 → 分析 → 输出报告”的完整练手项目。阶段五进阶方向。根据兴趣继续学习 Scrapy、NumPy、SQL、Flask 或机器学习。8.4 学习效率提升技巧不要只记笔记不敲代码每学一个知识点就马上运行示例。遇到报错先读报错信息最后一行再往上找具体行号。练习时尽量用真实数据哪怕数据量不大。把代码按功能拆成函数练习模块化思维。保留自己的工具函数库比如通用的请求函数、保存函数。9. 结语从环境搭建到爬虫抓取再到数据清洗和可视化展示我们已经走完了 Python 入门最核心的一条链路。你可以把标题中的“600 集教程”理解为一条完整的学习路径而不是真的需要看 600 个视频。真正重要的是把路径中的关键节点练熟基础语法能写脚本requests 能抓到数据pandas 能完成清洗统计matplotlib 能输出图表。接下来建议你立刻动手把本文第 4 节和第 5 节的代码复制到本地运行一遍。将单页爬虫扩展成多页爬虫保存更多数据。对抓取的数据做一个简单的分组统计和图表输出。如果你在练习过程中遇到任何报错欢迎把错误信息整理后到评论区一起讨论。代码是练出来的祝你能在这条学习主线上顺利走下去。