ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

携程景点与评论数据爬虫实战:Python实现与反爬应对详解

携程景点与评论数据爬虫实战:Python实现与反爬应对详解 简介基于Python的携程景点与评论数据爬虫源码适合作为毕业设计、课程设计或爬虫入门进阶项目面向计算机相关专业学生、爬虫初学者及希望快速搭建数据采集任务的开发者。压缩包共6个文件含2个Python爬虫脚本、1个配置INI、1个依赖TXT、1个项目说明MD及1个gitignore整体仅7KB代码与说明结构精简。爬虫可抓取景点基础信息并保存为csv同时按景点ID抓取评论到独立csv评论抓取支持随景点同步或单独运行两种模式每次运行前还会自动备份上一轮结果。项目说明中明确了开放时间与优惠政策的JSON格式、预估门票价格计算逻辑以及评论数据的用户ID、评论文本、发送时间戳、赞同数字段便于二次开发和字段理解。已有3185人学习下载作为Python爬虫实战与毕设方案具有较高参考价值。 爬虫类的项目在技术社区里从来都不缺热度尤其是“携程景点评论数据”这个方向——景点信息结构规整、评论数据量大且动态加载、平台又有一定的反爬策略几乎把爬虫入门到进阶会遇到的典型问题都覆盖了。我手上这个“基于python实现爬取携程景点数据与评论数据源码项目说明.zip”项目包就是一个相对完整、可以二次开发的样例。这篇博文不打算只贴代码而是把整套源码的设计思路、核心实现和我在调试过程中趟过的坑一并拆开讲清楚希望能给正在做类似数据采集项目或者拿爬虫当毕业设计、课程项目的读者一些参考。1. 这套源码项目到底做了什么模块划分与数据流设计拿到一个“源码项目说明”的压缩包第一件事不是急着跑起来而是先看项目的模块划分。这个项目包的结构大致是这样的trip_spider/ ├── config.py # 全局配置请求头、延时区间、存储配置等 ├── utils/ │ ├── http_client.py # 封装requests请求统一超时、重试、代理逻辑 │ └── parser.py # 景点与评论的解析工具函数 ├── spiders/ │ ├── scenic.py # 景点列表页详情页爬虫 │ └── comment.py # 评论数据爬虫 ├── storage/ │ └── mongo_store.py # MongoDB存储层同时支持CSV兜底 ├── run.py # 入口脚本控制整体采集流程 ├── requirements.txt └── README.md # 项目说明文档这个分层看起来简单但设计逻辑是清晰的配置和请求逻辑分离爬虫模块按数据对象拆分存储层单独抽象。好处在于如果你只想采集景点基础数据而不碰评论直接跑run.py --module scenic就行如果后续想换存储、加代理池也不用动解析逻辑。数据流向则是典型的“列表页挖入口→详情页补字段→评论页拉数据→统一入库”四步走。列表页拿到景点ID和基础名称详情页再带Cookie去拿完整字段评论页则通过XHR接口直接请求JSON。整个流程中最容易出问题的反而是第一步——列表页的翻页参数和页面结构变化频繁这部分后面细说。给初学者的建议是不要一上来就想着把所有页面都抓下来先把单页跑通、字段解析正确再上线全量采集。这套源码的run.py里也有一个--max-pages参数就是用来控制首次测试时的抓取规模的。2. 请求头、Cookie与访问节奏携程反爬应对的基本盘很多教学爬虫只教“加个User-Agent就能爬”但放到携程这种体量的平台上这远远不够。这个项目里http_client.py对请求头做了比较完整的封装值得展开说一下。2.1 请求头为什么不能只写一个User-Agent我用Chrome开发者工具抓了下正常浏览时的请求头发现除了User-Agent还有Referer、Accept-Language、Sec-Fetch-*这一系列字段。服务端的风控模型会综合判断如果请求头缺失关键字段哪怕频率很低也可能被标记为异常流量。这个项目的做法是把常用浏览器请求头固化在config.py里并内置了4~5套UA头轮换。实测下来单UA配合高频请求很容易触发滑块验证而多UA轮换、低频请求的情况下跑完整套流程基本不用人工介入。2.2 Cookie的处理策略首次手动获取后续自动携带评论接口的请求需要携带有效的登录态Cookie根源在于部分评论内容是按用户维度做个性化推荐的不登录也能看到总数但某些“精选评论”和“更多评论”接口会校验Cookie。源码里的处理方式是首次运行前需要你在浏览器里登录携程并复制Cookie填入config.py的COOKIE字段后续请求自动带上。这种做法在个人学习项目中完全够用比起自己维护登录态验证码、滑块、或者接第三方打码平台成本和稳定性都更可控。这里有一个非常重要的实操提醒Cookie在几个小时内就会失效而且一旦单IP请求量过大被封换Cookie也没用。所以项目里把超时重试机制放在了请求层——遇到403、412状态码时自动降低频率、等待更长时间后再试而不是立刻报错退出。2.3 访问节奏宁可慢不可断项目里默认的延时区间设置为2~4秒随机评论翻页间隔是3~5秒。说实话这个频率按“效率”标准看并不快但考虑到评论数据往往一个景点就是几百上千条控制节奏的意义不是省时间而是保证整个任务能完整跑下来。按照这个频率单个景点几百条评论大约需要十几分钟一整批跑完大约不会触发风控限制。另外源码里实现了简单的请求失败指数退避第一次失败等5秒第二次10秒第三次20秒最多5次这个机制在爬虫工程里属于基本操作但对稳定性影响极大。3. 景点列表页与详情页的解析实现从URL构造到字段清洗3.1 列表页URL参数拆解携程景点列表页的URL长这样https://you.ctrip.com/sight/{cityId}/{pageNo}.html但实际上在站点内搜索关键词后URL会变成带参数的形式比如https://you.ctrip.com/searchsite/?query杭州p1源码里封装了一个build_search_url(city, page)函数内部处理关键字URL编码和页码拼接。这个封装很有必要因为我在调试中发现直接改URL里的页码有时会返回相同的内容原因是部分页码是异步加载的。后来在源码里看到作者对列表页做了两类解析服务端渲染的静态列表直接用正则或XPath提取景点名称和链接异步加载的推荐列表从页面内嵌的window.__INITIAL_STATE__或XHR响应里取JSON。这两种情况分别处理兼容性会好很多。如果你自己写爬虫建议也先打开开发者工具看看列表页是静态HTML还是动态渲染这直接决定解析方案。3.2 详情页字段提取与清洗详情页的数据比列表页丰富得多包括景点名称、所在城市、评分、热度排名、地址、开放时间、建议游玩时长、简介和精选点评片段。这些字段分散在HTML的多个位置有些直接可见有些嵌在结构化JSON里。源码里针对详情页做了一套字段归一的处理逻辑字段提取位置清洗要点景点名称title标签 面包屑导航去掉“攻略-携程”等站点后缀评分summary模块的score节点统一转为float处理“4.5分”等格式开放时间详情区块合并多组时间段统一为“08:00-17:30”格式建议游玩时长详情区块提取“2-3小时”等文本简介描述区块去空白、去HTML标签、截断过长内容清洗这一步看着不起眼但对后续做数据分析影响极大。比如原始字段里有“暂无”或空值如果不统一处理入库之后做统计时会出现各种bug。这个项目里对所有字符串字段做了strip()和空值兜底数值字段做了类型转换异常捕获。3.3 去重的必要性列表页翻页过程中推荐位和搜索结果的景点会重复出现。源码里用景点ID作为唯一键在入库前做了一次内存去重再通过update_one(..., upsertTrue)写入MongoDB从根上避免重复数据。这个设计看起来简单但对评论爬虫来说特别重要——如果一个景点被重复采集评论表里就会出现大量重复记录影响后续的情感分析或统计准确性。4. 评论数据的动态加载与参数构造源码里最核心的部分评论接口是这个项目里最值得研究的部分因为它不是简单的GET请求就能搞定的。4.1 评论是异步XHR加载的你打开一个景点详情页往下滚动到评论区会发现评论数据是分页异步加载的网络请求里能看到类似这样的接口https://m.ctrip.com/restapi/soa2/13444/json/GetCommentList这是一个POST接口请求体是JSON包含景点ID、翻页游标、排序方式等参数。直接爬详情页HTML是拿不到评论数据的必须模拟这个请求。4.2 请求参数中那些“动态字段”怎么处理源码里比较关键的一点是请求体参数中除了景点ID和分页游标还包含一组类似_fxpcqlniredt这样的动态字段这些字段由服务端下发的某个JS脚本生成且不同会话值不一样。处理方式有三种直接复用浏览器里的值经测试有效期为1~2小时适合短时间内的单批采集从页面关联的JS文件里定位生成算法用Python复写一遍工程量大但一劳永逸用Selenium或Playwright渲染页面直接截获接口响应代码简单但并发能力和稳定性弱。这个项目采用的是第一种方式同时在注释里预留了第二种方案的扩展位置。从学习角度讲先把第一种跑通、理解请求响应结构再去看JS加密逻辑是性价比最高的路径。4.3 评论解析的字段设计评论接口返回的JSON结构比较清晰主要字段包括评论内容content评分score发布时间publishTime出游类型家庭亲子、情侣出游等以tag形式返回点赞数upCount用户昵称userName用户等级userLevel源码里把这些字段映射成统一的字典结构再写入MongoDB的comments集合。特别要注意的是评论内容里有部分标签符号如表情转义、换行符入库前要做HTML反转义和清洗否则后续做中文分词或情绪分析时会引入大量噪声。4.4 为什么不用Selenium全站爬取初学者可能觉得与其分析XHR请求、构造参数不如直接上Selenium模拟浏览器点到底简单粗暴。但实际跑过就会发现Selenium方案在评论数据量大的场景下效率太低——一个景点500条评论每页20条要翻25次每次等待页面渲染2~3秒光评论就要一分多钟更别提多景点并行时对CPU和内存的消耗。用纯requests构造请求同样500条评论大约只需要5~8秒。效率差的不是一点半点所以这个项目走的是“分析接口、模拟请求”这条更工程化的路线。5. 数据存储与项目说明文档能跑通只是起点交付才是终点5.1 MongoDB存储字段设计要点这个项目默认用MongoDB存储核心集合有两个scenics景点主数据字段包含景点ID、名称、城市、评分、地址、开放时间、简介等comments评论数据字段包含景点ID、评论内容、评分、发布时间、出游类型等并建立scenic_id和publish_time的联合索引。同时存储层做了CSV导出兜底——如果本机没装MongoDB或者读者希望快速浏览数据可以直接把结果导出为CSV文件。这个设置对课程设计和毕业设计场景很友好不用额外搭建数据库环境就能看到数据结果。字段设计上有一个细节值得学习评论表里冗余了scenic_name字段而不是只存scenic_id。原因是做后续统计分析时往往需要直接看“哪个景区的评论里面提到XX关键词最多”如果每次都要关联查询景点表数据量大时会有性能压力。当然冗余也会带来一致性问题但对于这种离线分析场景是完全可接受的取舍。5.2 断点续爬与日志输出评论爬虫跑起来动辄几十分钟甚至几个小时中途断网、封IP、程序异常都是常态。这个项目里加入了一个很实用的机制把当前抓到的景区索引记录到本地progress.json文件下次启动时自动从断点继续而不是从头再来。日志输出则分了两层控制台输出正常打印当前抓取进度、异常信息文件日志spider.log记录每次请求的URL、状态码、耗时、错误详情方便事后排查。我自己调试时有几次半夜跑任务挂了第二天早上就是靠spider.log里最后十几行日志快速定位是Cookie过期还是触发了验证码。这个习惯强烈建议养成。5.3 项目说明文档应该包含什么这个压缩包里的“项目说明”对于想学习的人来说价值不亚于源码本身。一份好的项目说明至少需要覆盖以下内容环境依赖Python版本、第三方库清单及安装命令运行方式从下载代码到最终跑出数据的分步指引配置说明每个配置项的含义、如何获取Cookie等关键信息数据字段字典每个输出字段的说明让使用数据的人不看代码也能明白字段含义常见问题Cookie失效、验证码触发、反爬限制的应对办法。README里还要明确声明“本项目仅供学习交流使用请遵守目标网站的Robots协议与相关法律法规合理控制访问频率”这既是基本的合规意识也是项目能否公开分享的前提。如果是拿去交作业、做课程设计这部分内容更要写得清楚。6. 实测中踩过的坑与这套源码的后续扩展思路6.1 列表页偶发的滑块验证即使频率控制得再稳跑十几个城市之后列表页还是偶尔会出现滑块验证页面。这个项目的处理方式是捕获到异常页面特征时当前任务停下来等待3到5分钟后再重试。实测下来大部分情况会自己恢复不需要人工干预。有些人会想到用OCR识别滑块缺口或接第三方打码平台但从学习和稳定性角度我并不建议一上来就搞这种复杂对抗。多数场景下降低并发、拉长延时、增加代理IP池才是风险更低、效果更持续的解法。6.2 评论翻页到后半段出现“暂无更多”的假页有个比较隐蔽的问题是评论接口在翻到某一页时即使后面还有数据也可能返回isEmptytrue导致爬虫误以为数据拉完了。排查后发现是某些景点评论区底部混入了“推荐其他景点”的模块干扰了游标判断。源码里加了一个保护逻辑连续两次翻页返回的数据量都为0且去重后条数不变才判定为真的到底否则继续翻页。这个小细节能有效避免数据漏采你自己实现评论采集时建议也加上。6.3 时间字段的坑评论里的publishTime返回的是毫秒级时间戳而有些接口又返回yyyy-MM-dd格式的字符串。源码里统一做了转换全部转成datetime对象写入数据库并在字段字典里注明格式。别看这个细节小真到做时间趋势分析的时候格式不统一会让人排查到崩溃。6.4 后续扩展方向这套源码后续可以扩展的方向其实非常清晰数据可视化基于入库数据用FlaskECharts做景点热度排行、评论情感极性分布的可视化页面增量更新每天的评论增量不大可以开发定时任务按景点ID追评最新一屏数据多城市并行用concurrent.futures.ThreadPoolExecutor控制线程数配合代理IP池实现多城市同时采集情感分析把评论内容接上SnowNLP或大模型的文本分类接口给每个景点生成评分舆情摘要。写到这里想分享一个个人习惯爬虫这种项目跑通只是第一步真正值钱的在于“你对自己采集的数据有没有一个完整、清晰的认识”。这套源码最大的价值不是让你直接拿走数据而是把“从页面分析到入库清洗”的完整链路示范了一遍。照着这个思路自己再动手写一次比单纯改参数跑通一遍要收获大得多。本文还有配套的精品资源点击获取
返回列表