Python爬虫实战:从携程旅游数据采集到毕业设计应用
每次看到学弟学妹为毕业设计的数据来源发愁,我就想起自己当年通宵写爬虫的日子。旅游推荐系统这类课题,最难的不是算法实现,而是如何获取足够多、足够真实的旅游数据。今天,我就以携程网为例,分享一套经过实战检验的Python爬虫方案,帮你高效完成数据采集工作。
1. 项目规划与前期准备
在开始写代码之前,我们需要明确几个关键问题:爬哪些数据?爬多少数据?数据怎么存储?这些问题直接关系到后续的工作量和实现难度。
数据字段规划建议包含以下核心维度:
- 景点信息:名称、评分、位置、简介、图片链接
- 酒店数据:名称、价格区间、设施服务、用户评价
- 美食推荐:餐厅名称、特色菜品、人均消费、地理位置
提示:字段不是越多越好,重点采集与推荐算法相关的核心属性,避免陷入数据沼泽。
技术选型上,轻量级组合requests + BeautifulSoup4足以应对大部分场景:
# 基础环境安装 pip install requests beautifulsoup4 pandas实际项目中,我建议采用以下目录结构保持代码整洁:
/travel_data_crawler ├── /data # 原始数据存储 ├── /utils # 工具函数 ├── config.py # 爬虫配置 ├── crawler.py # 主爬虫逻辑 └── requirements.txt # 依赖清单2. 携程网页结构解析实战
2.1 URL规律破解技巧
携程的URL设计有一定规律可循,以景点页面为例:
https://you.ctrip.com/sight/{城市代码}.html https://you.ctrip.com/sight/{城市代码}/s0-p{页码}.html通过分析多个城市页面,我整理出常见城市的代码对照表:
| 城市名称 | 代码标识 | 示例URL |
|---|---|---|
| 北京 | beijing1 | you.ctrip.com/sight/beijing1.html |
| 上海 | shanghai2 | you.ctrip.com/sight/shanghai2.html |
| 成都 | chengdu104 | you.ctrip.com/sight/chengdu104.html |
2.2 反爬应对策略
携程基础的反爬机制包括:
- User-Agent校验
- 请求频率限制
- 关键数据动态加载
建议的请求头配置:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Referer": "https://you.ctrip.com/", "Accept-Language": "zh-CN,zh;q=0.9" }3. 核心爬虫实现详解
3.1 景点信息抓取实例
以下是通过分析DOM结构提取景点数据的完整示例:
def get_sight_detail(url): response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 基础信息提取 name = soup.find('h1', {'class': 'sightname'}).get_text(strip=True) rating = soup.find('span', {'class': 'score'}).get_text(strip=True) # 详情区域解析 detail = { '位置': [dd.get_text(strip=True) for dd in soup.select('div.contentbox dl dd')], '特色': [li.get_text(strip=True) for li in soup.select('ul.introduce-list li')] } # 图片采集 images = [img['src'] for img in soup.select('div.carousel-inner img')] return { 'name': name, 'rating': float(rating), 'detail': detail, 'images': images }3.2 分页处理与数据存储
对于列表页的分页处理,建议采用生成器模式:
def generate_page_links(city_code, max_page=5): base_url = f"https://you.ctrip.com/sight/{city_code}/s0-p" for page in range(1, max_page+1): yield f"{base_url}{page}.html"数据存储推荐使用pandas直接转为结构化格式:
import pandas as pd def save_to_csv(data, filename): df = pd.DataFrame(data) df.to_csv(f'data/{filename}.csv', index=False, encoding='utf_8_sig')4. 数据清洗与质量管控
4.1 常见脏数据处理
采集到的原始数据通常需要以下清洗步骤:
文本规范化:
- 去除\xa0等特殊字符
- 统一日期格式
- 处理乱码问题
缺失值处理:
- 标记缺失字段
- 合理填充默认值
- 剔除无效记录
def clean_text(text): if not text: return None return (text.replace('\xa0', ' ') .replace('\n', ' ') .strip())4.2 数据验证方法
建议实现自动化校验机制:
def validate_record(record): required_fields = ['name', 'city', 'rating'] for field in required_fields: if field not in record or not record[field]: return False return True5. 毕业设计集成建议
有了基础数据后,可以进一步:
构建特征工程:
- 从评论文本提取关键词
- 计算景点热度指数
- 生成位置聚类特征
推荐算法适配:
- 协同过滤:基于用户行为
- 内容推荐:基于景点特征
- 混合推荐:结合多种策略
# 简单的内容推荐示例 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import linear_kernel def build_recommender(descriptions): tfidf = TfidfVectorizer(stop_words='english') tfidf_matrix = tfidf.fit_transform(descriptions) return linear_kernel(tfidf_matrix, tfidf_matrix)记得在项目文档中注明数据来源,并严格遵守robots.txt的爬取限制。这套方案在我指导的3个毕业设计中都取得了不错的效果,关键是要保持数据采集的针对性和可持续性。