Python爬虫实战:携程景点及评论数据采集全解析

发布时间:2026/9/8 21:41:57
Python爬虫实战:携程景点及评论数据采集全解析 简介一套基于 Python 实现的携程景点数据与评论数据爬虫源码及项目说明适合毕业设计、课程设计或 Python 爬虫进阶练习能够抓取景点基础数据并关联抓取评论解决数据获取与整理环节的常见需求。压缩包共 6 个文件含两个 Python 脚本、配置文件、依赖清单、gitignore 和说明文档整体仅 7KB便于快速定位核心逻辑。爬虫提供两种运行模式既可在景点数据爬取过程中同步抓取评论也可分步运行两个脚本每次运行前自动备份上一次景点结果为 back.csv避免数据丢失。配置文件中可通过开关控制是否抓取评论依赖清单便于复现环境项目对数据字段做了说明价格与最低价格为原始返回数据门票价格可调整 GetTicketPrice 函数开放时间与优惠政策以 JSON 格式存储评论数据包含用户 ID、评论文本、发送时间戳和赞同数。目前已有 3185 人学习/下载适合课程设计、毕设数据采集或爬虫工程化入门参考。1. 项目概述与目标拆解这个项目的标题很清楚用 Python 爬取携程的景点数据和用户评论数据并且给了一份完整的源码和项目说明文档。对于想入门爬虫、或者需要一份真实业务场景练手数据的同学来说这是一个非常典型的综合性实战案例——它不止是写几个请求那么简单而是把“列表页抓取 → 详情页解析 → 接口翻页 → 数据清洗 → 落盘存储”完整串了起来刚好覆盖了企业里做数据采集的日常流程。我在拿到这套源码时第一反应是去看了它的项目说明文档里面明确写了两个核心数据目标一是景点基础信息包含景点名称、所在城市、评分、热度、门票参考价等二是对应景点的用户评论包括评论内容、评分、发布时间、用户昵称。这两类数据组合起来能做的事情非常多比如做城市旅游热度分析、景点口碑对比、评论情感倾向分析甚至可以作为推荐系统的原始特征来源。当然如果是个人学习和技术研究这份数据的价值主要体现在“完整的链路实操”上。适合谁来参考这套东西我认为有三类人第一类是刚学完 Python 基础、想找一个真实网站练手爬虫的新手这个项目的复杂程度刚好不会上来就甩给你一套分布式爬虫架构把人吓退第二类是工作中需要定期采集旅游类公开数据的开发人员可以把里面的请求参数和解析逻辑直接改改拿来用第三类是想做旅游数据分析的爱好者用它拿数据比手动复制粘贴高效得多。但有一点必须先说清楚爬取公开数据必须遵守目标网站的 robots 协议和服务条款控制请求频率数据仅用于个人学习研究不能商用。2. 技术选型与整体方案设计2.1 为什么选 requests BeautifulSoup 而不是 Scrapy项目源码里并没有用 Scrapy 这样的大框架而是基于 requests BeautifulSoup 进行开发。这个选择我比较认同因为项目目标是“单机运行、快速拿到数据、便于理解”而不是构建一套大规模采集系统。requests 处理 HTTP 请求足够轻量BeautifulSoup 做 HTML 解析上手成本极低任何一个写过几天 Python 的人都能看懂。如果一上来就用 Scrapy虽然调度和去重更完善但对于一个教学向或小规模采集项目来说框架本身的学习成本反而会淹没核心逻辑。另外一个现实原因是携程的景点列表页和部分内容是通过接口动态加载的Scrapy 处理这类请求时需要额外配置中间件和异步下载器而 requests 直接模拟接口调用反而更直观。源码里对接口返回的 JSON 数据和页面 HTML 做了双轨处理——能用接口拿的数据就优先走接口拿不到的再从 HTML 里解析这种方式在实际工作中非常实用。2.2 反爬应对策略在源码里的体现爬虫项目绕不开反爬问题这套源码里值得一提的有这么几处设计。第一它在请求头里做了完整的伪装User-Agent 不是默认的 Python-requests 字符串而是模拟了真实浏览器的 UA同时携带了 Referer 字段让服务器看起来像是从正常的页面流转过来的请求。第二所有请求都走了 Session 机制这样能保持会话连贯性尤其对需要 Cookie 的服务端验证方式比较友好。第三点做得比较巧妙的是请求频率控制。源码里对每个景点详情页请求之间设置了随机延时延时范围大致在 1 到 3 秒之间避免出现规律的请求间隔。很多人写爬虫不重视这一块结果请求频率一高IP 直接进黑名单前面解析逻辑写得再好也没用。控制频率不是怕事而是为了让爬虫更“体面”地工作既不干扰目标站点的正常运行也能保证自己的采集任务稳定持续。注意随机延时范围不要写成固定值固定间隔比高频请求更容易被识别。2.3 数据存储方案的取舍源码里数据存储选了 CSV 而不是数据库这个设计很务实。CSV 的好处有三个一是无需额外安装数据库服务环境依赖最少二是编码问题可控用 utf-8-sig 写入可以直接用 Excel 打开不乱码三是这份数据量级在几百到几千条评论时CSV 的读写性能完全够用。如果换成 MySQL 或 MongoDB虽然查询能力更强但对于这种规模的项目反而显得笨重。当然源码在存储层做了扩展接口如果你要改成数据库存储只需要替换 save_to_csv 函数内部实现即可不影响前面的采集逻辑。这种低耦合设计我比较欣赏也建议新手在写爬虫时养成这个习惯——存储方式与抓取逻辑分离后面维护起来会轻松很多。3. 源码结构分析与项目配置3.1 目录结构与核心文件职责我拿到源码后第一件事是梳理了目录结构这套项目的文件组织非常清晰没有把全部逻辑堆在一个文件里而是按职责做了拆分。核心模块包括请求发送模块、页面解析模块、数据存储模块、任务调度模块以及一个用于配置常量参数的 config 文件整体结构如下携程景点爬虫项目/ ├── config.py # 配置请求头、URL、延时范围等常量 ├── spider.py # 主调度入口控制采集流程 ├── request_util.py # 封装 requests 请求逻辑统一异常处理 ├── parser.py # 解析景点列表、详情、评论数据 ├── storage.py # CSV 存储与数据清洗 ├── requirements.txt # 依赖清单 └── README.md # 项目说明文档这种拆分方式的优势在于如果目标网站的页面结构变了只需要去改 parser.py如果请求被限制了只需要调 request_util.py。真正的项目里维护成本往往不在写代码而在改代码好的模块划分能让你改一个地方不用牵动其他逻辑。这里也提醒一句拿到别人的源码第一件事就是先看目录结构和说明文档别急着运行。3.2 环境依赖与安装步骤项目说明里给出了依赖清单运行所需的核心库其实只有 requests、beautifulsoup4、lxml 三个。lxml 作为 BeautifulSoup 的解析引擎比默认的 html.parser 快很多而且对残缺 HTML 的容错性更好建议安装。安装命令如下pip install requests beautifulsoup4 lxml如果你用的是 Python 3.6 以上版本这些库的兼容性完全没有问题。我在本地用 Python 3.10 测试过运行过程没出现因版本导致的语法错误。这一点对新手特别友好——很多老项目拿到手第一关就是环境配置失败这套源码至少没有把精力耗在环境坑上。另外提醒一句启动前最好新建一个虚拟环境别把依赖装到系统全局环境里避免以后不同项目之间互相干扰。3.3 运行入口与参数调整项目运行入口是 spider.py默认直接执行python spider.py就会开始采集。不过在真正运行之前建议先打开 config.py 看一眼可配置的参数。源码里预设了一个默认城市和默认页码范围你需要根据自己的实际需求修改起始 URL 和采集页数。有些时候接口参数里还隐藏着城市 ID这个 ID 可以在网页端的搜索栏里找到对应城市的编码修改 config 里对应的参数即可。一个小细节源码里的 log 输出做得比较完善每个步骤都有打印信息比如“正在抓取第 1 页景点列表”“成功解析 15 条景点数据”“开始抓取景点评论共 2 页”。运行的时候不要嫌这些输出烦它们就是你的进度条也能帮助定位出错位置。4. 核心抓取逻辑与关键实现细节4.1 景点列表页的抓取与解析整个项目的起点是景点列表页。源码先请求携程某个城市的景点列表 URL然后用 BeautifulSoup 解析出每个景点的名称、评分、热度、简介等基础信息并提取出景点详情页的链接。列表页的解析重点在于选择器的定位源码里用了 CSS 选择器比如div.scenic_item这样的容器选择器来圈定单个景点的范围然后再在范围内查找具体字段。这里有一个特别容易踩的坑页面里有些评分是“暂无”或者“0.0”源码里对这类异常值做了兜底处理转换为空字符串或默认值。很多新手写解析时假设所有字段都存在结果一遇到缺失值整个程序就报 AttributeError。源码里大量使用了 try-except 包裹解析逻辑这个习惯很重要——网页数据永远是脏的不存在的字段不是异常而是常态。关于翻页list 页的翻页参数通常是页码号拼接在 URL 的查询参数上。源码里把 URL 模板和页码做了格式化处理循环请求直到达到设定页数。这里要特别说一下翻页时建议不要只依赖页面上的“下一页”按钮因为按钮的跳转 URL 有时候是 JavaScript 动态生成的直接用页码参数拼接更稳定。4.2 详情页与评论接口的请求方式景点详情页本身包含的信息不够全面尤其是评论数据通常是由前端通过 Ajax 接口动态加载的。源码里对详情页的处理逻辑是先请求景点页面的 HTML解析出景点 ID然后拿着这个 ID 去请求评论接口。这个思路是这类动态加载网站的标准打法核心就一句话——找到数据真正的来源接口而不是去解析渲染后的页面。评论接口的请求返回的是 JSON 格式里面包含了评论列表、总评论数、总页码等信息。源码里解析 JSON 时用了字典逐层提取的方式比如data[data][commentList]。这里需要特别提醒接口返回的 JSON 层级往往比想象中更深而且字段名会带一些前缀或业务字段建议你在浏览器开发者工具里先手动分析一遍接口返回结构再写解析代码不要上来就猜。评论数据里比较有价值的字段包括评论内容、评分、发表时间、用户信息等。源码里对评论内容做了空白字符清理去掉换行和多余空格这个细节虽然不起眼但直接关系到后续做中文分词或情感分析时的数据质量。存储评论时建议把景点名称也一起存进去这样后面做分析的时候不需要再关联查询。4.3 翻页采集与游标机制评论接口的翻页方式和列表页不太一样很多网站的评论接口用的是游标翻页而非页码翻页。游标参数一般是上一次请求返回的最后一个评论 ID 或时间戳源码里对这一块做了适配从响应中提取下一个游标值然后拼接到下一次请求的参数中。这个机制是评论采集的核心逻辑假如你只看到页码参数就盲目套用很可能抓到第 2 页后返回的数据和第 1 页完全相同。4.4 去重策略与断点续爬源码里还做了评论去重用景点 ID 加评论 ID 组合成一个唯一键在内存里维护一个集合每解析一条评论就检查是否已经存在。为什么需要去重因为翻页过程中有些接口可能会出现数据重复返回特别是游标机制处理不当的时候。去重逻辑虽然简单但在数据质量把控上非常关键。断点续爬方面源码的设计是如果某个景点的评论抓取失败会记录下当前景点 ID 到一个失败列表里主流程结束后单独重试。这种设计避免了“一个景点失败导致全部任务终止”的尴尬局面在实际运行中很有用。我在实测中就遇到过某个景点因为网络波动导致超时的情况靠着重试机制跳过了这个坑。5. 常见问题与排查技巧实录我在复现这套源码时踩过几个坑也帮朋友排查过类似问题这里整理成一张速查表供遇到同样情况的人参考。问题现象可能原因解决方案请求返回 403 ForbiddenUser-Agent 或请求头被识别更换为真实浏览器 UA补充 Referer 字段部分景点的评论抓不到该景点暂无评论或接口分页不同检查响应中的评论总数为 0 时跳过写入 CSV 后 Excel 打开乱码编码使用了 utf-8改为 utf-8-sig 编码写入解析时提示找不到指定标签页面结构更新或反爬返回验证页打印响应内容前 500 字确认返回的是正常数据抓了十几条后 IP 被临时限制请求频率太高增大延时范围到 3~5 秒必要时使用代理池评论接口返回空数据需要携带 Cookie 或特定请求头从浏览器开发者工具中复制完整请求头5.1 验证码与 IP 限制的应对实测过程中携程的验证码出现频率不算高但一旦连续高频请求就会在页面里插入滑块验证。遇到这种情况不要试图硬刚破解最理智的做法是立刻停止当前的采集任务降低请求频率等待一段时间再继续。源码里没有内置验证码识别模块正确的用法是把它当作一个信号——说明你的爬虫已经被注意到了。IP 限制的另一种表现是返回数据突然全部变成同一个模板页面这时候检查一下响应内容往往能看到它返回了一个安全验证页面。如果项目需要长期采集建议配置代理池并在请求失败时自动切换代理。但在本地小规模学习场景里控制频率加适当延时已经足够。5.2 动态加载内容的两种处理路径拿列表页来说如果你发现请求到的 HTML 里没有景点数据而是只有一段 JavaScript 代码说明数据是异步加载的。源码里的应对方式是直接找 XHR 接口。判断方法很简单打开浏览器的开发者工具切到 Network 面板刷新页面看哪些请求返回的是 JSON 数据那里面往往就是你要的数据源。另一种处理方式是用 Selenium 或 Playwright 模拟真实浏览器渲染但重量级明显更高项目里没有采用因为接口请求方式更高效。5.3 数据清洗与字段规整从网页上拿到的原始数据基本都是脏的比如评分字段可能是“4.5分”需要去掉“分”字评论时间可能是“2024-03-15 10:30:00”也可能只是“03-15”格式不统一。源码里在存储之前做了一层统一的字段处理把数值类字段转成浮点数把时间字段统一格式。这一步在后续做分析时能省下大量时间建议不要省略。如果你有 pandas 基础也可以在这一步之后再用 pandas 做二次清洗效率会更高。提示数字字段建议在写入时就保证是数值类型不要留着“分”“元”这些单位到后续处理否则排序和聚合时会出大问题。6. 合规边界与项目后续扩展建议这个项目虽然从技术上实现了数据采集但我也得把合规这事多说几句。在爬取任何网站数据之前应该查看目标网站的 robots.txt 文件和服务条款尊重网站声明的不允许抓取的路径。本项目的定位是个人学习和技术研究采集到的数据应当限定在本地环境使用不能用于商业用途也不应该二次传播。爬虫本身是中性技术工具关键是使用目的和使用方式。控制请求频率、不抓取非公开数据、不绕过登录验证这三点是底线。站在技术学习的角度这套源码可以做的扩展方向其实很多。比如把存储从 CSV 升级为 SQLite 或 MySQL让数据支持更复杂的查询再比如接入简单的 sentiment analysis用 SnowNLP 对评论做情感倾向打分就能直接输出一个景点口碑的正负面比例还可以把爬虫部署到服务器上配合定时任务实现每周自动采集一次。每一步扩展都不难但能把数据采集链路完整走下来本身就比单纯看教程学 API 调用有价值得多。我个人在复现这个项目时最大的收获其实不是代码本身而是它模拟了一个真实场景目标网站会更新结构、接口会变化、数据会缺失、网络会波动你必须学会在不确定性里写出健壮的逻辑。这也是爬虫项目和普通后端开发最大的区别所在——你的代码运行环境有一半不受你控制。如果你也想练手建议不要停留在“跑通源码”这一步而是亲手改几个解析规则替换成别的旅游网站看看同样的思路能不能复用。真正把一套逻辑吃透比复制十个项目源码有用得多。本文还有配套的精品资源点击获取