人生苦短,我用python
虽然还是有15天才放五一的假,
但是我的心早已经在旅游的路上了~
本文源码:点击此处跳转文末名片获取
趁现在,先来用python做一个旅游攻略
知识点:
requests
parsel
csv
第三方库:
requests
parsel
模块安装:
- 按住键盘 win + r, 输入cmd回车
- 打开命令行窗口, 在里面输入 pip install 模块名
开发环境:
python 3.8
+python安装包 安装教程视频
+pycharm 社区版 专业版 及 激活码文末名片获取
代码实现步骤:
1. 向目标网站发送网络请求
2. 获取数据 网页源代码
3. 筛选我们需要的数据 所有的详情页链接
4. 向 每一个详情页 链接发送网络请求
5. 获取数据 网页源代码
6. 提取数据
[出发日期 天数 人均费用 人物 玩法 地点 浏览量...]
7. 保存数据
8. 多页爬取
9. 做一个可视化分析 旅游景点推荐
导入模块
import random
import time
import requests
import parsel
import csv
爬取旅游wang数据
1. 向目标网站发送网络请求
csv_qne = open('去哪儿.csv', mode='a', encoding='utf-8', newline='')
csv_writer = csv.writer(csv_qne)
csv_writer.writerow(['地点', '短评', '出发时间', '天数','人均费用','人物','玩法','浏览量','详情页'])
for page in range(1, 201):
url = f'https://travel.qunar.com/travelbook/list.htm?page={page}&order=hot_heat'
2. 获取数据 网页源代码
html_data = response.text
3. 筛选我们需要的数据 所有的详情页链接
selector = parsel.Selector(html_data)
url_list = selector.css('body > div.qn_mainbox > div > div.left_bar > ul > li > h2 > a::attr(href)').getall()
for detail_url in url_list:
detail_id = detail_url.replace('/youji/', '')
detail_url = '这里放网址' + detail_id
4. 向 每一个详情页 链接发送网络请求
response_1 = requests.get(detail_url)
5. 获取数据 网页源代码
data_html_1 = response_1.text
6. 提取数据
selector_1 = parsel.Selector(data_html_1)
title = selector_1.css('.b_crumb_cont *:nth-child(3)::text').get()
comment = selector_1.css('.title.white::text').get()
count = selector_1.css('.view_count::text').get()
date = selector_1.css('#js_mainleft > div.b_foreword > ul > li.f_item.when > p > span.data::text').get()
days = selector_1.css('#js_mainleft > div.b_foreword > ul > li.f_item.howlong > p > span.data::text').get()
money = selector_1.css('#js_mainleft > div.b_foreword > ul > li.f_item.howmuch > p > span.data::text').get()
character = selector_1.css('#js_mainleft > div.b_foreword > ul > li.f_item.who > p > span.data::text').get()
play_list = selector_1.css('#js_mainleft > div.b_foreword > ul > li.f_item.how > p > span.data span::text').getall()
play = ' '.join(play_list)
print(title, comment, date, days, money, character, play, count, detail_url)
csv_writer.writerow([title, comment, date, days, money, character, play, count, detail_url])
time.sleep(random.randint(3, 5))
csv_qne.close()
数据分析代码
import pandas as pd
from pyecharts.commons.utils import JsCode
from pyecharts.charts import *
from pyecharts import options as opts
data = pd.read_csv('去哪儿_数分.csv')
data
data.info()
data = data[~data['地点'].isin(['攻略'])]
data = data[~data['天数'].isin(['99+'])]
data
data.drop_duplicates(inplace=True)
data['人均费用'].fillna(0, inplace=True)
data['人物'].fillna('独自一人', inplace=True)
data['玩法'].fillna('没有', inplace=True)
data['天数'] = data['天数'].astype(int)
data = data[data['人均费用'].values>200]
data = data[data['天数']<=15]
data
data = data.reset_index(drop=True)
data
data = data.reset_index(drop=True)
data
def Month(e):
m = str(e).split('/')[2]
if m=='01':
return '一月'
if m=='02':
return '二月'
if m=='03':
return '三月'
if m=='04':
return '四月'
if m=='05':
return '五月'
if m=='06':
return '六月'
if m=='07':
return '七月'
if m=='08':
return '八月'
if m=='09':
return '九月'
if m=='10':
return '十月'
if m=='11':
return '十一月'
if m=='12':
return '十二月'
data['旅行月份'] = data['出发时间'].apply(Month)
data['出发时间']=pd.to_datetime(data['出发时间'])
data
import re
def Look(e):
if '万' in e:
num1 = re.findall('(.*?)万',e)
return float(num1[0])*10000
else:
return float(e)
data['浏览次数'] = data['浏览量'].apply(Look)
data.drop(['浏览量'],axis = 1,inplace = True)
data['浏览次数'] = data['浏览次数'].astype(int)
data.head()
data1 = data
data1['地点'].value_counts().head(10)
loc = data1['地点'].value_counts().head(10).index.tolist()
print(loc)
loc_data = data1[data1['地点'].isin(loc)]
price_mean = round(loc_data['人均费用'].groupby(loc_data['地点']).mean(),1)
print(price_mean)
price_mean2 = [1630.1,1862.9,1697.9,1743.4,1482.4,1586.4,1897.0,1267.5,1973.8,1723.7]
m2 = data1['地点'].value_counts().head(10).index.tolist()
n2 = data1['地点'].value_counts().head(10).values.tolist()
bar=(
Bar(init_opts=opts.InitOpts(height='500px',width='1000px',theme='dark'))
.add_xaxis(m2)
.add_yaxis(
'目的地Top10',
n2,
label_opts=opts.LabelOpts(is_show=True,position='top'),
itemstyle_opts=opts.ItemStyleOpts(
color=JsCode("""new echarts.graphic.LinearGradient(
0, 0, 0, 1,[{offset: 0,color: 'rgb(255,99,71)'}, {offset: 1,color: 'rgb(32,178,170)'}])
"""
)
)
)
.set_global_opts(
title_opts=opts.TitleOpts(
title='目的地Top10'),
xaxis_opts=opts.AxisOpts(name='景点名称',
type_='category',
axislabel_opts=opts.LabelOpts(rotate=90),
),
yaxis_opts=opts.AxisOpts(
name='数量',
min_=0,
max_=120.0,
splitline_opts=opts.SplitLineOpts(is_show=True,linestyle_opts=opts.LineStyleOpts(type_='dash'))
),
tooltip_opts=opts.TooltipOpts(trigger='axis',axis_pointer_type='cross')
)
.set_series_opts(
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(type_='average',name='均值'),
opts.MarkLineItem(type_='max',name='最大值'),
opts.MarkLineItem(type_='min',name='最小值'),
]
)
)
)
bar.render_notebook()
bar=(
Bar(init_opts=opts.InitOpts(height='500px',width='1000px',theme='dark'))
.add_xaxis(loc)
.add_yaxis(
'人均费用',
price_mean2,
label_opts=opts.LabelOpts(is_show=True,position='top'),
itemstyle_opts=opts.ItemStyleOpts(
color=JsCode("""new echarts.graphic.LinearGradient(
0, 0, 0, 1,[{offset: 0,color: 'rgb(255,99,71)'}, {offset: 1,color: 'rgb(32,178,170)'}])
"""
)
)
)
.set_global_opts(
title_opts=opts.TitleOpts(
title='各景点人均费用'),
xaxis_opts=opts.AxisOpts(name='景点名称',
type_='category',
axislabel_opts=opts.LabelOpts(rotate=90),
),
yaxis_opts=opts.AxisOpts(
name='数量',
min_=0,
max_=2000.0,
splitline_opts=opts.SplitLineOpts(is_show=True,linestyle_opts=opts.LineStyleOpts(type_='dash'))
),
tooltip_opts=opts.TooltipOpts(trigger='axis',axis_pointer_type='cross')
)
.set_series_opts(
markline_opts=opts.MarkLineOpts(
data=[
opts.MarkLineItem(type_='average',name='均值'),
opts.MarkLineItem(type_='max',name='最大值'),
opts.MarkLineItem(type_='min',name='最小值'),
]
)
)
)
bar.render_notebook()
data1['天数'].value_counts()
data1['旅行时长'] = data1['天数'].apply(lambda x:str(x) + '天')
data1
data1['人物'].value_counts()
m = data1['浏览次数'].sort_values(ascending=False).index[:].tolist()
data1 = data1.loc[m]
data1 = data1.reset_index(drop = True)
data1
data1['旅行月份'].value_counts()
word_list = []
for i in data1['玩法']:
s = re.split('\xa0',i)
word_list.append(s)
dict = {}
for j in range(len(word_list)):
for i in word_list[j]:
if i not in dict:
dict[i] = 1
else:
dict[i]+=1
#print(dict)
list = []
for item in dict.items():
list.append(item)
for i in range(1,len(list)):
for j in range(0,len(list)-1):
if list[j][1]<list[j+1][1]:
list[j],list[j+1] = list[j+1],list[j]
print(list)
data1['旅行月份'].value_counts()
m1 = data1['人物'].value_counts().index.tolist()
n1 = data1['人物'].value_counts().values.tolist()
pie = (Pie(init_opts=opts.InitOpts(theme='dark', width='1000px', height='800px'))
.add("", [z for z in zip(m1,n1)],
radius=["40%", "65%"])
.set_global_opts(title_opts=opts.TitleOpts(title="去哪儿\n\n出游结伴方式", pos_left='center', pos_top='center',
title_textstyle_opts=opts.TextStyleOpts(
color='#FF6A6A', font_size=30, font_weight='bold'),
),
visualmap_opts=opts.VisualMapOpts(is_show=False,
min_=38,
max_=641,
is_piecewise=False,
dimension=0,
range_color=['#9400D3', '#008afb', '#ffec4a', '#FFA500','#ce5777']),
legend_opts=opts.LegendOpts(is_show=False, pos_top='5%'),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}", font_size=12),
tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{b}: {c}"),
itemstyle_opts={"normal": {
"barBorderRadius": [30, 30, 30, 30],
'shadowBlur': 10,
'shadowColor': 'rgba(0,191,255,0.5)',
'shadowOffsetY': 1,
'opacity': 0.8
}
})
)
pie.render_notebook()
#%%
m3 = data1['出发时间'].value_counts().sort_index()[:]
m4 = m3['2021'].index
n4 = m3['2021'].values
#%%
m3['2021'].sort_values().tail(10)
``````c
#%% md
## 出游时间分析
#%%
line = (
Line()
.add_xaxis(m4.tolist())
.add_yaxis('',n4.tolist())
)
line.render_notebook()
#%%
line = (
Line()
.add_xaxis(m4.tolist())
.add_yaxis('',n4.tolist())
)
line.render_notebook()
(完整代码文末名片获取)
综上述分析可得到一些结论:
- 去三亚哈哈哈哈哈哈哈哈哈哈
- 去三天就好了,保留一下新鲜感