ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

零基础Python爬虫与数据分析实战:从环境搭建到可视化

零基础Python爬虫与数据分析实战:从环境搭建到可视化 零基础自学Python的人很大比例不是倒在语法难度上而是倒在“不知道下一步做什么”上。今天打开一个视频学了爬虫明天又去看数据分析后天换成机器学习学了两三周以后能看懂每一个片段却写不出一个从抓取数据到输出结果的完整脚本。这篇文章针对的就是这种情况。核心路径是把爬虫和数据分析当作一条主线以零基础为前提通过一个最小可复现的工程示例把 Python 环境搭建、requests 抓取数据、BeautifulSoup 解析、pandas 清洗与分析、matplotlib 可视化这几段能力串联起来。读完并对照示例操作后你应该能独立完成一个“公开接口数据采集 → 数据清洗 → 统计分析 → 图表输出”的小项目并知道学习过程中哪些地方最容易卡住卡住之后该从哪里排查。1. 零基础自学Python最常见的失败原因1.1 为什么“看视频”不等于“会编程”很多零基础学习者陷入同一个误区把“看完一个视频系列”当成“学会一门语言”。视频教程通常按知识点组织先讲变量、再讲循环、再讲函数每一集看起来都能听懂但视频之间缺少项目级关联。真实工程是按依赖关系组织内容的一个爬虫脚本里既要处理 HTTP 请求又要处理 JSON 数据还要把结果写入文件一个数据分析脚本里既要处理缺失值又要处理数据类型还要保证统计口径正确。这些能力无法靠“看”获得必须靠“改代码、跑代码、查报错”获得。另一个常见问题是照抄代码。跟着视频把示例代码逐行敲一遍当时的运行结果也是对的但换一个网址、换一条数据代码立刻失效。原因通常不是 Python 语法变了而是没理解数据结构和接口返回格式。爬虫返回的是字典还是列表数据分析读入的是字符串还是数值这些细节决定代码能不能继续运行。学习阶段最重要的不是把语法背下来而是建立“先看数据长什么样再决定怎么写代码”的习惯。1.2 爬虫和数据分析为什么适合作为入门主线爬虫和数据分析是非常适合零基础起步的两个方向因为它们形成了一条完整的数据处理链路。爬虫负责获取原始数据数据分析负责把原始数据变成结论两个方向共用同一批 Python 基础知识变量、字符串、列表、字典、循环、函数、文件读写、异常处理。学完这条主线后你掌握的并不是孤立的语法片段而是一条能运行、能输出结果的技术路径。这两个方向还有很强的反馈激励作用。requests发送请求后能看到状态码pandas能快速输出统计表matplotlib能生成一张图表。每个步骤都有明确结果遇到问题时报错信息也相对明确适合自学。相比之下一上来就学面向对象或者异步编程概念脱离数据场景很难坚持。需要说明的是这里不主张“把 Python 所有语法学完再动手”。更有效的方式是先掌握最常用的变量、条件、循环、函数然后立刻进入爬虫和数据分析项目在项目里遇到什么补什么。等主线路走通后再回头补正则表达式、面向对象、装饰器等进阶语法理解成本会明显下降。1.3 这篇文章的学习路径与预期结果全文按实际操作顺序展开。第一件事是搭建 Python 开发环境包括 Python 本体、编辑器、虚拟环境和核心依赖库。第二步是掌握爬虫基础重点是requests发起请求和 BeautifulSoup 解析数据。第三步是掌握数据分析基础重点是pandas的 DataFrame 和数据清洗操作。第四步是把前面内容合并成一个最小项目抓取一个公开接口的数据保存成 JSON 文件再用 pandas 统计和分析最后用 matplotlib 生成可视化图表。第五步是常见问题排查第六步是学习路线和建议。这篇文章不需要你之前有 Python 基础但需要能正常访问 Python 官网和安装软件。正文中所有代码都基于学习环境运行生产环境需要的日志、重试、数据库、定时调度等内容会在最后单独说明。2. 开发环境准备从Python安装到编辑器配置2.1 Python版本选择与安装环境准备是零基础学习者最容易忽略的一步。不少人直接在命令行输入python发现命令不存在或者在安装过程中把 Python 装到了带空格的目录里导致后续 pip 安装依赖时出现一堆路径问题。Python 版本选择以官方稳定版为准。到 python.org 的 Downloads 页面下载对应操作系统的安装包即可。Windows 安装时务必勾选“Add Python to PATH”否则命令行无法直接执行python命令。安装路径建议使用默认路径或者选择纯英文且没有空格的目录。中文路径在某些第三方库的场景下可能触发编码或路径解析问题学习阶段尽量避开。安装完成后打开命令提示符或终端执行两条验证命令python --version pip --version如果输出类似Python 3.12.x和关联的 pip 版本信息说明安装成功。如果提示“python 不是内部或外部命令”说明 PATH 没有生效重新运行安装包勾选 Add Python to PATH或者手动把 Python 安装目录添加到环境变量。macOS 也可以使用brew install pythonLinux 可以使用系统包管理器但官方安装包在版本控制上更直接。2.2 编辑器选择VSCode还是PyCharm写 Python 不需要一开始就使用重型 IDE但需要一个能高亮语法、能直接运行脚本的编辑器。两种常见选择VSCode 和 PyCharm 社区版。对比项VSCodePyCharm 社区版安装包大小相对小相对大配置成本需要安装 Python 扩展配置轻微开箱即用识别解释器更直观适合阶段适合想了解工具链配置的初学者适合想减少环境配置干扰的初学者调试体验配置后同样好用图形化调试体验较好常见用途通用编辑器也适合其他语言专注 PythonPyCharm 专业版功能更全如果之前没有接触过任何代码编辑器从 PyCharm 社区版开始可以把更多精力放在代码本身。如果希望长期使用一个通用编辑器同时写 Python、前端或配置文件VSCode 是更轻量的选择。两者都能满足本文的代码运行需求关键不是选择哪个而是确保创建的脚本文件能被当前解释器识别。2.3 创建虚拟环境并安装核心依赖为什么不直接往全局 Python 环境里安装依赖因为不同项目可能依赖不同版本的库。今天用requests 2.31另一个老项目可能要用requests 2.20全局共用一个环境会产生冲突。虚拟环境的作用是在项目目录里隔离出一套独立的 Python 运行环境让每个项目拥有自己的依赖版本。在项目目录下执行mkdir python_study cd python_study python -m venv venvvenv是虚拟环境目录名这里也叫venv这是工程里最常见的命名方式。创建完成后Windows 激活命令为venv\Scripts\activatemacOS 或 Linux 激活命令为source venv/bin/activate激活后命令行前面会出现(venv)标识。接下来安装本文需要的核心库pip install requests beautifulsoup4 lxml pandas matplotlib如果网络下载较慢可以临时使用国内镜像源例如pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests beautifulsoup4 lxml pandas matplotlib这里不使用代理也不需要修改任何系统网络配置。安装完成后执行pip list只要能看到requests、pandas、matplotlib、beautifulsoup4、lxml这些包就说明依赖安装成功。2.4 环境验证运行第一个Python脚本环境是否真正可用要以“运行一个脚本并看到输出”为准。在python_study目录下新建文件hello.py写入import sys import requests import pandas as pd print(Python version:, sys.version) print(requests version:, requests.__version__) print(pandas version:, pd.__version__)然后在命令行运行python hello.py正常的输出会显示 Python 版本和两个库的版本号。如果提示ModuleNotFoundError: No module named requests说明当前命令行使用的 Python 环境里没有安装依赖需要确认是否激活了虚拟环境并用where pythonWindows或which pythonmacOS/Linux查看当前解释器路径。注意不要只验证程序能启动还要验证依赖库能正常导入。很多初学者在没激活虚拟环境的情况下运行pip install结果库装到了全局环境脚本里仍然找不到模块。3. 爬虫基础用requests抓取数据并解析3.1 HTTP请求的基本工作过程爬虫的本质是写一段程序模拟浏览器或客户端向服务器发送 HTTP 请求然后处理服务器返回的数据。服务器返回的常见格式有三种HTML 页面、JSON 数据结构、文件流图片、PDF。学习阶段建议先从 JSON 格式的公开接口入手因为 JSON 结构清晰不需要处理复杂标签适合理解请求和响应的基本流程。一次完整的 HTTP 请求包含几个关键部分请求方法GET、POST、URL、请求头headers、请求参数params 或 body。服务器返回的结果包含状态码、响应头和响应体。状态码是最快的排错线索200 表示成功403 表示禁止访问404 表示资源不存在500 表示服务器内部错误。requests 库封装了这些底层细节不需要理解 socket 和 HTTP 报文就能发起请求。但理解状态码和请求头仍然很重要因为后续几乎所有爬虫问题都需要从这两处开始排查。3.2 requests库的核心参数requests.get()是最常用的方法。下面是完整的最小示例import requests url https://jsonplaceholder.typicode.com/todos params {_limit: 5} headers {User-Agent: Mozilla/5.0 (learning-python)} resp requests.get(url, paramsparams, headersheaders, timeout10) print(resp.status_code) data resp.json() print(data)这里使用了 JSONPlaceholder 这个公开演示接口它专门用于学习 HTTP 请求不需要登录也没有复杂的鉴权逻辑。解释几个核心参数参数作用使用建议url请求的目标地址必须完整包含协议params拼接到 URL 查询字符串中的参数字典格式requests 会自动处理编码headers设置请求头常见为 User-Agent至少设置一个常见的 User-Agenttimeout等待响应的时间单位秒生产环境必须设置避免无限等待resp.json()会尝试把响应体解析成 Python 对象。上面的接口返回一个列表列表中每个元素是一个字典包含userId、id、title、completed四个字段。请求一旦成功后续的数据解析和统计分析都建立在这个结构上。3.3 数据解析JSON和HTML如果接口返回 JSON直接使用resp.json()即可。如果目标是 HTML 页面就需要用 BeautifulSoup 解析。以下是一个最小 HTML 解析示例from bs4 import BeautifulSoup html div idmain span classtitlePython/span span classtitle爬虫/span /div soup BeautifulSoup(html, lxml) for node in soup.select(.title): print(node.get_text())select()方法接收 CSS 选择器.title表示选取所有classtitle的元素。get_text()提取标签内文本。如果系统中lxml解析器安装失败可以把解析器参数换成html.parser这是 Python 内置解析器不需要额外安装但容错能力相对弱一些。解析逻辑的核心原则是先打印一小段响应内容观察数据结构再写选择器或下标。不要凭猜测写复杂解析逻辑。比如先用print(resp.text[:500])看前 500 个字符确认返回的是 HTML 还是 JSON再决定下一步代码。3.4 批量型、增量型和垂直型爬虫的应用场景在工程设计中爬虫通常按采集方式分为三种类型。理解它们能帮助你根据任务选择合适的实现思路。类型核心思路适用场景注意事项批量型爬虫一次性抓取全部历史数据初始化数据、迁移历史记录请求量大容易被限流建议分批慢速抓取增量型爬虫定期抓取从上一次位置以来的新增数据持续更新价格、文章、订单等数据需要保存游标或时间戳记录抓取位置垂直型爬虫聚焦某一领域或某一站点的数据行业资讯、商品信息、特定平台数据覆盖面窄但解析规则可以做得更深学习阶段建议先把批量型逻辑跑通一次请求抓取一批数据保存到本地文件。之后把请求放入循环增加时间间隔记录上次抓取位置就形成了增量型雏形。垂直型爬虫需要更多领域知识适合在主线路走通之后再深入研究。4. 数据分析基础pandas清洗与聚合4.1 数据从哪里来在本文的流程中数据分析的数据来源是爬虫保存的 JSON 文件。真实业务中数据可能来自数据库、Excel 表格、日志文件或者第三方接口。pandas 提供一个统一的数据结构 DataFrame可以把这些来源的数据加载成一张内存表格再进行筛选、计算和统计。一个典型的场景是爬虫抓取了数据但原始数据并不干净要么字段缺失要么存在重复记录要么类型不对。如果不做清洗直接统计结果可能完全错误。所以数据分析的第一步不是计算而是“看数据”确认数据结构、字段含义和异常情况。4.2 DataFrame基础操作pandas 读入 JSON 的方式如下import pandas as pd df pd.read_json(data/todos.json) print(df.shape) print(df.head()) print(df.info())df.shape返回行列数df.head()显示前 5 行df.info()显示每列的非空值和数据类型。拿到一张 DataFrame 后常见的操作有# 选择一列 print(df[completed]) # 布尔条件筛选 finished df[df[completed] True] print(finished.head()) # 按用户分组统计完成数量 result df.groupby(userId)[completed].sum() print(result)布尔筛选是 pandas 最重要的操作之一。df[completed] True会得到一个布尔序列再把布尔序列传给df[]就只保留符合条件的行。分组统计时completed字段是布尔值sum()会统计每个分组内True的个数也就是完成数量。4.3 缺失值和重复值处理爬虫得到的数据经常存在三个问题字段缺失、重复记录、类型错乱。处理顺序建议是先检查缺失再去重最后处理类型。# 查看每列缺失值数量 print(df.isna().sum()) # 删除完全重复的行 df df.drop_duplicates(subset[id], keepfirst) # 缺失值填充 df df.fillna()关键原则是不要盲目删除。isna()可以定位缺失但删除之前要先看缺失比例。如果缺失占比很小直接删除如果占比较大考虑是字段本身允许为空还是抓取逻辑出了问题。drop_duplicates(subset[id])表示按id列去重保留第一次出现的记录。对带主键性质的数据去重通常以业务唯一键为准而不是以整行完全一致为准。类型问题同样容易踩坑。如果 JSON 里某个字段有时是字符串、有时是数字pandas 读入后该列类型可能变成object做数值计算时会报错。这时需要先用pd.to_numeric()转换df[value] pd.to_numeric(df[value], errorscoerce)errorscoerce表示无法转换的值变成NaN之后再统一处理缺失值。4.4 用matplotlib做初步可视化可视化是为了让统计结果更容易理解。常用图表有折线图、柱状图、饼图和散点图。在本文项目中适合用柱状图展示每个用户的完成数量对比。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False labels [用户1, 用户2, 用户3] values [8, 12, 5] plt.figure(figsize(8, 5)) plt.bar(labels, values) plt.xlabel(用户) plt.ylabel(完成数) plt.title(各用户完成数量) plt.tight_layout() plt.savefig(data/simple_chart.png, dpi150) plt.show()中文字体是需要提前处理的问题。matplotlib 默认字体不包含中文字符标题、坐标轴如果出现中文可能显示成方框。plt.rcParams[font.sans-serif] [SimHei]的作用是把默认字体切换为黑体。需要说明的是SimHei是 Windows 常见字体macOS 上通常不存在这时可以改成[PingFang SC]或[Arial Unicode MS]。更稳妥的做法是在画图前先确认当前系统有哪些中文字体。5. 最小闭环项目抓取公开数据并完成分析5.1 项目目标与数据来源现在把前面内容合并成一个完整项目。项目目标是从公开演示接口抓取待办事项数据保存到本地使用 pandas 统计每个用户的待办总数和已完成数量最后用 matplotlib 生成可视化图表。数据源使用 JSONPlaceholder 的/todos接口。该接口返回 200 条 JSON 数据每条包含四个字段字段含义类型userId用户编号numberid待办事项编号numbertitle待办事项标题stringcompleted是否完成boolean选择这个接口是因为它公开、不需要登录、返回 JSON 格式适合学习阶段。真实项目里换成其他公开接口时只需要调整 URL 和字段名整体流程完全一致。5.2 项目结构与完整代码项目目录结构如下python_study/ ├── venv/ ├── data/ ├── fetch_data.py ├── analyze.py └── visualize.pyfetch_data.py负责抓取数据并保存成 JSONimport json import requests url https://jsonplaceholder.typicode.com/todos resp requests.get(url, timeout10) resp.raise_for_status() data resp.json() with open(data/todos.json, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2) print(f抓取完成共 {len(data)} 条数据)resp.raise_for_status()会在状态码不是 200 时抛出异常避免把错误页面当成正常结果保存。ensure_asciiFalse让 JSON 文件保存中文时保持可读indent2让文件格式更清晰。analyze.py负责读取 JSON清洗数据并输出统计结果import pandas as pd df pd.read_json(data/todos.json) print(原始数据形状:, df.shape) print(df.head()) df df.drop_duplicates(subset[id], keepfirst) result df.groupby(userId).agg( total(id, count), completed(completed, sum) ).reset_index() result[完成率] (result[completed] / result[total] * 100).round(2) print(result) result.to_csv(data/result.csv, indexFalse, encodingutf-8-sig)groupby按userId分组agg同时统计total和completed。completed是布尔值sum()会统计True的数量。reset_index()把分组索引转成普通列。encodingutf-8-sig导出的 CSV 在 Excel 中打开时不会出现中文乱码。visualize.py负责读取统计结果并绘图import pandas as pd import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False result pd.read_csv(data/result.csv) plt.figure(figsize(10, 6)) plt.bar(result[userId], result[completed], label已完成) plt.bar( result[userId], result[total] - result[completed], bottomresult[completed], label未完成 ) plt.xlabel(用户ID) plt.ylabel(任务数) plt.title(各用户待办完成情况) plt.legend() plt.tight_layout() plt.savefig(data/result.png, dpi150) plt.show()这里使用堆叠柱状图。第一个plt.bar画已完成数量第二个plt.bar的bottom参数把未完成部分叠在已完成部分上方整根柱子的高度就是该用户的待办总数。5.3 参数说明与代码逻辑文件作用关键函数或参数输出文件fetch_data.py抓取接口数据requests.get、raise_for_status、json.dumpdata/todos.jsonanalyze.py清洗与统计read_json、drop_duplicates、groupby.agg控制台打印、data/result.csvvisualize.py可视化plt.bar、savefig、tight_layoutdata/result.png三个文件之间通过文件传递数据没有直接代码依赖。这样做的好处是每段逻辑可以单独运行、单独调试抓取失败时不需要看分析代码统计结果不对时不需要重新抓取数据。5.4 运行顺序与预期结果先激活虚拟环境然后依次执行三个脚本python fetch_data.py python analyze.py python visualize.py预期结果是fetch_data.py输出“抓取完成共 200 条数据”analyze.py打印分组统计表visualize.py弹出图表窗口并保存data/result.png。analyze.py的统计表大致类似下面这样userId total completed 完成率 0 1 20 11 55.00 1 2 20 12 60.00 ...如果某一步报错优先确认上一步的输出文件是否存在。例如analyze.py报错“文件不存在”说明fetch_data.py没有成功生成todos.json如果visualize.py中文字体显示异常说明需要修改字体配置。6. 常见问题排查6.1 网络请求失败或超时现象requests抛出ConnectionError或ReadTimeout异常脚本中断。可能原因目标接口暂时无法访问、本地网络波动、没有设置timeout导致长时间等待。检查方式先在浏览器中打开 URL确认接口本身可用再在代码中打印resp.status_code如果使用公开演示接口多尝试几次。解决方案为requests.get()设置timeout可以在请求外套一层try...except实现重试如果目标接口仍不可用换一个公开接口测试。预防建议学习阶段不要把代码绑定在某一台机器或某一次网络状态上请求逻辑要考虑失败场景。6.2 请求返回403或内容为空现象状态码为 403或响应内容不是预期数据而是验证页面。可能原因服务端要求User-Agent请求频率过高被限流访问了不允许公开访问的路径。检查方式打印resp.status_code和resp.text[:500]观察返回内容。解决方案在headers中设置常见的浏览器User-Agent降低请求频率增加时间间隔。注意这里不讨论绕过验证码、突破登录限制等操作。学习阶段只请求公开接口遵守网站的用户协议和 robots 规则。技术练习应在合规边界内进行。6.3 中文乱码现象控制台打印内容出现类似é“的乱码或写入文件后中文无法正常显示。可能原因响应字符集和解析字符集不一致控制台编码不是 UTF-8写文件时没有指定encoding。检查方式打印resp.encoding和resp.apparent_encoding观察resp.text前几百字符。解决方案在requests中指定resp.encoding utf-8写文件时使用encodingutf-8Windows 控制台执行chcp 65001切换到 UTF-8 代码页。预防建议凡是涉及文本读写统一显式指定 UTF-8 编码不要依赖系统默认编码。6.4 pandas读取文件报错现象pd.read_json()或pd.read_csv()抛出ParserError、ValueError。可能原因JSON 顶层不是数组或对象而是其他结构字段类型不一致文件路径不正确。检查方式先用文本编辑器打开文件确认数据结构再在 Python 中打印原始 JSON 类型。解决方案如果 JSON 是对象内部包含数组通常需要先定位数组字段再传入pd.DataFrame()如果字段类型混合用pd.to_numeric(..., errorscoerce)统一处理。6.5 虚拟环境问题现象pip install成功但import时报ModuleNotFoundError。可能原因pip 和 Python 不在同一个环境中激活虚拟环境失败当前目录下存在其他 Python 环境干扰。检查方式执行where pythonWindows或which pythonmacOS/Linux确认解释器路径在venv目录下。解决方案重新激活虚拟环境使用python -m pip install ...强制让 pip 与当前 Python 绑定。预防建议在项目目录下始终使用同一个虚拟环境不要混合使用全局环境。7. 学习路线与工程实践建议7.1 一周学习路径天数学习内容完成目标第1天Python 安装、编辑器配置、基本语法能运行第一个脚本理解变量、列表、字典第2天requests 请求、HTTP 状态码、JSON 解析能抓取公开接口数据并打印第3天BeautifulSoup 解析、CSS 选择器能从简单 HTML 页面提取指定内容第4天pandas 基础操作、DataFrame 筛选和分组能对 JSON 数据做统计第5天matplotlib 画图、中文字体问题能生成柱状图和折线图第6天完成本文最小闭环项目跑通抓取、分析、可视化全流程第7天复盘和扩展能独立改换数据源或统计字段这里的关键是每一天都要有可见输出。第 1 天可以只输出几行文本第 2 天必须看到真实接口返回的数据第 3 天必须能从 HTML 中提取到目标文本。没有输出的学习很容易变成“只看不练”。7.2 学习爬虫必须守住的边界爬虫是一项很实用的技能但在学习和使用过程中要明确边界。只请求公开接口不访问需要登录才能查看的数据遵守网站 robots 协议和服务条款控制请求频率不影响网站正常访问不采集个人隐私数据不将数据用于恶意用途不绕过登录、验证码、会员权限等访问控制机制。本文的示例选择了公开演示接口正是为了让学习过程不涉及真实网站的数据保护机制。后续自己练习时建议优先选择官方提供 API 的平台、政府公开数据接口、以及明确允许爬取的演示站点。这样既能训练技术又能避免法律和合规风险。7.3 生产环境还需要补什么本文示例是学习环境的最小实现进入生产环境后还需要补齐大量工程细节。请求层面需要增加异常重试、请求限速、日志记录和 User-Agent 轮换数据层面需要把 JSON 文件换成 SQLite、MySQL 等数据库并加入增量更新逻辑运行层面需要把脚本部署到服务器用定时任务触发同时配置监控和告警。以下清单可以作为生产化改造的起点请求设置超时失败时按指数退避重试。日志记录每次请求的状态码、耗时和异常堆栈。请求之间增加时间间隔降低服务端压力。数据库写入使用批量插入并设置唯一键防重。增量任务记录上次抓取位置或时间戳。脚本运行失败时通过邮件或企业通知发送告警。配置对外置不硬编码 URL、账号和路径。7.4 后续扩展方向爬虫方向可以继续学习 Scrapy 框架、Selenium 或 Playwright、分布式爬虫和消息队列。数据分析方向可以继续学习 NumPy、数据清洗最佳实践、更丰富的可视化图表和统计分析。两个方向交汇之后还可以进入机器学习、量化分析、自然语言处理等更深的领域。每次练习建议沿用同一条主线确定一个数据源提出一个分析问题完成一个可运行脚本输出一份可解释的结果。把本文的流程复制到不同数据源上练习三次以上直到不需要看文档也能写出请求、清洗和统计代码再进入下一阶段。把环境搭起来、把第一份公开数据抓到本地、用 pandas 统计出结果、把结果画成一张图这个过程远比背完一章语法有用。后续学习可以围绕新的数据源和分析目标继续复制这套流程换一个公开接口换一组统计需求甚至把脚本挂到定时任务里实现增量更新。建议先不要急着学太多工具用这套最小流程连续做三次以上直到遇到问题能自己根据报错定位再进入 Scrapy、数据库和更复杂的分析场景。
返回列表