Python 分析去哪儿旅游攻略数据并制作可视化图表
前言
在节假日出行高峰期间,如何制定合理的旅游预算和行程规划是许多旅行者关心的问题。通过数据分析,我们可以从海量的旅游攻略中提取出有价值的信息,例如费用分布、热门目的地、出行时长等。本文将以 Python 为工具,演示如何抓取去哪儿网的旅游攻略数据,并进行清洗、存储与可视化分析,帮助读者掌握网络爬虫与数据可视化的基本流程。
本文演示了如何使用 Python 爬虫技术抓取去哪儿网旅游攻略数据,并利用 pandas 和 pyecharts 进行数据清洗与可视化分析。通过 requests 和 parsel 库获取页面信息,解析出标题、费用、行程等关键字段,最终生成费用分布、出行时间等统计图表,帮助旅行者制定预算合理的出游计划。

在节假日出行高峰期间,如何制定合理的旅游预算和行程规划是许多旅行者关心的问题。通过数据分析,我们可以从海量的旅游攻略中提取出有价值的信息,例如费用分布、热门目的地、出行时长等。本文将以 Python 为工具,演示如何抓取去哪儿网的旅游攻略数据,并进行清洗、存储与可视化分析,帮助读者掌握网络爬虫与数据可视化的基本流程。
本项目主要使用以下 Python 第三方库:
requests:用于发送 HTTP 请求,获取网页内容。parsel:基于 lxml 的解析库,支持 CSS 选择器和 XPath。pandas:强大的数据处理与分析库。pyecharts:基于 ECharts 的可视化库,支持生成交互式图表。csv:Python 内置模块,用于读写 CSV 文件。安装命令如下:
pip install requests parsel pandas pyecharts
我们需要访问去哪儿网的旅游攻略列表页面。通过分析浏览器开发者工具(F12),可以发现该页面是一个 HTML 结构,数据隐藏在 DOM 元素中。URL 参数包含分页、排序、月份及价格区间等信息。
示例 URL 结构:
https://travel.qunar.com/travelbook/list.htm?page=1&order=hot_heat&month=10_11_12&avgPrice=2
为了防止被服务器识别为爬虫,我们需要设置 User-Agent 请求头,模拟真实浏览器的行为。同时,建议添加延时机制,避免请求过快导致 IP 被封禁。
代码实现:
import requests
import time
url = 'https://travel.qunar.com/travelbook/list.htm'
params = {
'page': 1,
'order': 'hot_heat',
'month': '10_11_12',
'avgPrice': '2' # 对应特定价格区间
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
try:
response = requests.get(url, params=params, headers=headers)
response.encoding = 'utf-8'
if response.status_code == 200:
print('请求成功')
else:
print(f'请求失败,状态码:{response.status_code}')
except Exception as e:
print(f'发生错误:{e}')
使用 parsel 库对返回的 HTML 文本进行解析。通过 CSS 选择器定位到每一篇攻略的容器元素,并提取标题、作者、日期、费用、行程等关键字段。
.list_item。代码实现:
from parsel import Selector
import csv
def parse_data(html_content):
selector = Selector(text=html_content)
items = selector.css('.list_item')
data_list = []
for item in items:
try:
title = item.css('.tit a::text').get().strip()
user_name = item.css('.user_name a::text').get().strip()
date_raw = item.css('.date::text').get().strip()
days = item.css('.days::text').get().strip()
photo_nums = item.css('.photo_nums::text').get().strip()
fee = item.css('.fee::text').get().strip()
people = item.css('.people::text').get().strip()
trip_tag = item.css('.trip::text').get().strip()
places_raw = ''.join(item.css('.places ::text').getall()).split('行程')
place_start = places_raw[0].replace('途经:', '').strip() if len(places_raw) > 0 else ''
place_end = places_raw[-1].replace(':', '').strip() if len(places_raw) > 1 else ''
href = item.css('.tit a::attr(href)').get().split('/')[-1]
detail_link = f'https://travel.qunar.com/travelbook/note/{href}'
# 尝试从日期字符串中提取年份和月份
year = month = ''
if date_raw:
parts = date_raw.split('-')
if len(parts) >= 3:
year = parts[0]
month = parts[1]
elif len(parts) >= 2:
year = parts[0]
month = parts[1]
record = {
'标题': title,
'昵称': user_name,
'日期': date_raw,
'年份': year,
'月份': month,
'耗时': days,
'照片数': photo_nums,
'费用': fee,
'人员': people,
'标签': trip_tag,
'途径': place_start,
'行程终点': place_end,
'详情页': detail_link
}
data_list.append(record)
except Exception as e:
continue
return data_list
将解析后的数据保存为 CSV 文件,便于后续使用 Pandas 进行分析。注意指定编码格式为 UTF-8,防止中文乱码。
def save_to_csv(data, filename='data.csv'):
if not data:
return
fieldnames = list(data[0].keys())
with open(filename, mode='w', encoding='utf-8-sig', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
print(f'数据已保存至 {filename}')
使用 Pandas 读取 CSV 文件,并进行初步的数据概览。
import pandas as pd
df = pd.read_csv('data.csv')
print(df.head())
print(df.info())
统计不同费用区间的攻略数量,使用柱状图展示,比饼图更适合比较类别差异。
from pyecharts.charts import Bar
from pyecharts import options as opts
# 清理费用列中的非数字字符以便排序
fee_cleaned = df['费用'].str.replace('元', '').astype(float)
df['费用数值'] = fee_cleaned
# 分组统计
fee_dist = df['费用数值'].value_counts().sort_index()
bar = (
Bar(init_opts=opts.InitOpts(width="800px", height="400px"))
.add_xaxis([str(x) for x in fee_dist.index])
.add_yaxis("攻略数量", [int(y) for y in fee_dist.values])
.set_global_opts(
title_opts=opts.TitleOpts(title="费用分布情况"),
xaxis_opts=opts.AxisOpts(name_rotate=60),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
)
# bar.render_notebook() # 实际使用时取消注释
分析用户的平均出行天数以及同行人数分布,了解主流旅行模式。
from pyecharts.charts import Pie
# 出行时间
time_dist = df['耗时'].value_counts()
c_time = (
Pie()
.add("", [list(z) for z in zip(time_dist.index, time_dist.values)])
.set_global_opts(title_opts=opts.TitleOpts(title="出行时间分布"))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
# 人员构成
people_dist = df['人员'].value_counts()
c_people = (
Pie()
.add("", [list(z) for z in zip(people_dist.index, people_dist.values)])
.set_global_opts(title_opts=opts.TitleOpts(title="同行人员分布"))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
观察不同月份的攻略发布热度,辅助判断旅游旺季。
month_dist = df['月份'].value_counts().sort_index()
c_month = (
Bar()
.add_xaxis([str(x) for x in month_dist.index])
.add_yaxis("发布数量", [int(y) for y in month_dist.values])
.set_global_opts(title_opts=opts.TitleOpts(title="月份发布趋势"))
)
本文完整演示了从数据采集、解析、存储到分析可视化的全流程。通过 Python 爬虫技术,我们能够低成本地获取大量公开的旅游数据,并利用可视化手段直观呈现数据背后的规律。这对于个人旅行规划、旅游行业市场分析均具有参考价值。
在实际应用中,还可以进一步优化爬虫的反爬能力(如使用代理 IP、动态 JS 渲染处理),增加更多维度的分析指标(如目的地热度词云、用户情感分析等)。希望本文能为初学者提供清晰的入门指引。
注:本文代码仅供学习参考,请遵守相关法律法规及目标网站的 robots.txt 协议,合理使用网络资源。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online