Número público: You Er Hut
Autor: Peter
Editor: Peter
Hola a todos, mi nombre es Peter~
Este artículo es la séptima ciudad del turismo sobre orugas Python en el país: Lanzhou, principalmente para presentar las atracciones e información gastronómica de Lanzhou.
Lo escribí antes 厦门、长沙、西安、大连、苏州、成都
, si está interesado, puede leerlo o puede usarse como una guía de viaje ~
Lanzzhou
Un extracto de una introducción a Lanzhou en Wikipedia:
Lanzhou , conocida como Lan , también conocida como Jincheng , es la capital de la provincia de Gansu de la República Popular China , una importante base industrial y centro de transporte integral en el noroeste de China aprobado por el Consejo de Estado, una importante ciudad nodo de la Ruta de la Seda Cinturón económico, y una de las ciudades centrales importantes en la región occidental. Primero, la tercera ciudad más grande en la región noroeste, la ciudad central en la "aglomeración urbana Lanzhou- Xining ", está ubicada en la parte central de la provincia de Gansu.
Las siguientes son las regiones administrativas de Lanzhou:
Información de rastreo
La información rastreada es principalmente la información de comida y atracciones de Lanzhou:
import pandas as pd
import re
import csv
import json
import requests
import random
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
# 绘图相关
import jieba
import matplotlib.pyplot as plt
from pyecharts.globals import CurrentConfig, OnlineHostType # 事先导入,防止不出图
from pyecharts import options as opts # 配置项
from pyecharts.charts import Bar, Scatter, Pie, Line, HeatMap, Funnel, WordCloud, Grid, Page # 各个图形的类
from pyecharts.commons.utils import JsCode
from pyecharts.globals import ThemeType,SymbolType
Rastreo de atracciones
El siguiente código de rastreo de una sola página utiliza un método de rastreo regular:
url = "https://travel.qunar.com/p-cs300026-lanzhou-jingdian-1-1"
headers = {"user-agent": "个人请求头"}
response = requests.get(url=url,headers=headers)
result = response.content.decode()
Si la fuente HTML analizada contiene comillas dobles, la cadena más externa después del método re.findall() usa comillas simples
En 3]:
# 1-景点中文名称
cn_title = re.findall('class="cn_tit">(.*?)<span class="en_tit">.*?</span>',result,re.S)
print("长度:",len(cn_title))
cn_title
长度: 10
Fuera[3]:
['甘肃省博物馆',
'黄河铁桥',
'白塔山公园',
'黄河母亲雕塑',
'兰州新区长城影视基地',
'石佛沟国家森林公园',
'黄河索道',
'五泉山公园',
'兰州极地海洋世界',
'兰山公园']
En [4]:
# 2-景点英文名称
en_title = re.findall('<span class="en_tit">(.*?)</span>.*?</span>',result,re.S)
print("长度",len(en_title))
en_title
长度 10
Fuera[4]:
['Gansu Provincial Museum',
'Yellow River Steel Bridge',
'Baitashan Park',
'Yellow River Mother Sculpture',
'Lanzhou Xinqu Changcheng Yingshi Base',
'Lanzhou Shifo Valley National Forest Park',
'Huanghe Ropeway',
'Wuquanshan Park',
'Lanzhou Ocean World',
'Lanshan Park']
En [5]:
# 3-strategy攻略数量
strategy = re.findall('class="icon_strategy" title="攻略"></span>(.*?)</div>',result, re.S)
print(len(strategy))
strategy
10
Fuera[5]:
['50', '94', '40', '35', '0', '1', '3', '2', '0', '1']
En [6]:
# 4-comment点评数量
comment = re.findall('class="icon_comment" title="点评"></span>(.*?)</div>',result, re.S)
print(len(comment))
comment
10
Fuera[6]:
['1295', '2948', '793', '489', '23', '30', '46', '354', '146', '80']
En [7]:
# 5-景点地点(长沙景点排名、宁乡景点排名等)
# 我们只需要"景点排名"之前的信息,代表的是地址
location = re.findall('去过(.*?)的驴友', result, re.S)
print(len(location))
location
10
Fuera[7]:
['兰州', '兰州', '兰州', '兰州', '永登', '兰州', '兰州', '兰州', '兰州', '兰州']
En [8]:
# 6-景点排名
ranking = re.findall('class="ranking_sum".*?class="sum">(.*?)</span>',result,re.S)
print(len(ranking))
ranking
10
Fuera[8]:
['7', '3', '11', '10', '0%', '56', '1', '17', '5', '49']
En [9]:
# 7-驴友
# 有多少的驴友也去过这个地方
lvyou = re.findall('class="comment_sum">.*?class="sum">(.*?)</span>',result,re.S)
print(len(lvyou))
lvyou
10
Fuera[9]:
['35%', '58%', '30%', '30%', '0%', '0%', '0%', '1%', '0%', '1%']
En [10]:
# 8-景点简介
abstract = re.findall('class="desbox">(.*?)</div>',result,re.S)
print(len(abstract))
abstract
10
Fuera[10]:
['通过丰富精彩的展品了解古丝绸之路、唐蕃古道上多民族的文化和历史。',
'兰州市最为经典的地标建筑,夜晚时铁桥彩灯闪耀,周围夜景非常漂亮。',
'登上山顶可以俯瞰壮观的兰州城市全景,山间建筑古朴树木众多,让人感受舒心惬意。',
'黄河母亲雕塑现已经成为兰州的标志性雕塑,也代表着兰州形象。',
'', # 空值
'',
'',
'公园景点以五眼名泉和佛教古建筑为主,园内丘壑起伏,林木葱郁,环境清幽。',
'',
'公园就位于山顶制高点上,可俯瞰兰州全景。']
El resultado final del rastreo:
Rastreo de comida
El código para el rastreo de información de una sola página también se rastrea en función de expresiones regulares: un total de 200 páginas
En 2]:
url = "https://travel.qunar.com/p-cs300026-lanzhou-meishi?page=1"
headers = {"user-agent": "个人请求头"}
response = requests.get(url=url,headers=headers)
result = response.content.decode()
cn_title
En 3]:
cn_title = re.findall('cn_tit">(.*?)</span>.*?countbox',result,re.S)
En [4]:
print(len(cn_title))
cn_title
10
Fuera[4]:
['正宁路小吃夜市',
'安泊尔牛肉面(北滨河路店)',
'兰州大众巷美食街',
'马三洋芋片(兰州总店)',
'清真·马安军辣子牛肉面',
'安泊尔',
'杜记甜食',
'孙子烤肉(皋兰路店)',
'大漠烤肉(盘旋路店)',
'清真•白建强牛肉面']
puntaje
En [5]:
score = re.findall('cur_score">(.*?)</span>.*?total_score',result,re.S)
En [6]:
print(len(score))
score
10
Fuera[6]:
['4.3', '4.5', '--', '4.3', '3.5', '5.0', '4.2', '3.5', '4.2', '0.0']
cuadro de sublista
Primero extraiga todo el cuadro de lista secundaria y luego extraiga cada subelemento dentro de él por separado
En [7]:
sublistbox = re.findall('sublistbox">(.*?)</div>', result, re.S)
sublistbox[:1]
Fuera[7]:
['<dl class="sublist_item clrfix"><dt class="sub_tit">人\u3000均</dt><dd class="sub_des">¥ 63</dd></dl><dl class="sublist_item clrfix"><dt class="sub_tit">地\u3000址</dt><dd class="sub_des des_line">白银路街道永昌南路正宁路</dd></dl><dl class="sublist_item clrfix"><dt class="sub_tit">推荐菜</dt><dd class="sub_des des_line">当地口味\t美食街\t老字号\t深夜营业</dd></dl><div class="desbox"><span class="img_doublequote img_l"></span><span class="txt">吃客云集的小吃街,地道吃食令人回味。<span class="img_doublequote img_r"></span></span>']
En [8]:
type(sublistbox)
Fuera[8]:
list
En [9]:
# 对sublistbox单独提取
Precio promedio
En [10]:
person_avg = []
for i in range(len(sublistbox)):
try:
if "均" in sublistbox[i]:
person_avg.append(re.findall('¥ (.*?)</dd></dl>',sublistbox[i],re.S)[0])
else:
person_avg.append(0)
continue
except:
person_avg.append(0)
En [11]:
print(len(person_avg))
person_avg
10
Fuera[11]:
['63', '27', 0, '19', '17', 0, '14', '58', '58', '18']
Dirección
En [12]:
address = []
for i in range(len(sublistbox)):
try:
if "址" in sublistbox[i]:
address.append(re.findall('址.*?des_line">(.*?)</dd></dl>',sublistbox[i],re.S)[0])
else:
address.append("无")
continue
except:
address.append("无")
En [13]:
print(len(address))
address
10
Fuera[13]:
['白银路街道永昌南路正宁路',
'北滨河路754号(龙源斜对面)',
'兰州市城关区大众巷',
'通渭路79号',
'七里河北街忠云宾馆斜对面',
'北滨河路金城关3号',
'大众巷72号',
'皋兰路4号(虹云宾馆北侧)',
'东岗西路451号',
'雁滩路3423号']
Platos recomendados
En [14]:
recommand = []
for i in range(len(sublistbox)):
try:
if "推荐菜" in sublistbox[i]:
recommand.append(re.findall('推荐菜.*?des_line">(.*?)</dd></dl>',sublistbox[i],re.S)[0])
else:
recommand.append("无")
continue
except:
recommand.append("无")
En [15]:
print(len(recommand))
recommand
10
Fuera[15]:
['当地口味\t美食街\t老字号\t深夜营业',
'美食林风味\t当地口味\t肉汤萝卜\t三泡台\t酱牛肉\t蜂蜜油香\t安泊尔牛肉面\t牛筋\t雪梨汤\t牛腱子肉\t甜醅子\t灰豆子',
'马子禄牛肉面\t香满楼\t俊杰羊肉泡馍馆\t杜维成甜食店',
'美食林风味\t当地口味\t炸年糕\t里脊肉饼\t洋芋片\t年糕\t辣年糕\t胡萝卜汁\t豆腐皮\t油炸年糕\t炸糖年糕\t胡萝卜素饮料\t豆皮\t牛肚',
'无',
'无',
'当地口味\t下午茶\t老字号\t美食林风味\t高担酿皮\t甜胚子\t牛肉馅饼\t粽子\t八宝醪糟\t炒粉\t茹记杏皮水\t热晶糕\t甜醅子\t牛奶鸡蛋醪糟\t甜醅\t灰豆子',
'无',
'深夜营业\t美食林臻选\t羊腰\t凉面\t烤羊肚\t羊汤\t羊肉泡馍\t烤羊排\t烤饼\t烤羊板筋\t烤肉串\t烤羊皮\t杏皮水\t烤茄子',
'特色小吃\t当地口味\t其他\t兰州拉面\t牛肉面\t牛肉']
Evaluación
En [16]:
comment = []
for i in range(len(sublistbox)):
try:
if "desbox" in sublistbox[i]:
comment.append(re.findall('.*?txt">(.*?)<span class="img_doublequote img_r">',sublistbox[i],re.S)[0])
else:
comment.append("无")
continue
except:
comment.append("无")
En [17]:
print(len(comment))
comment
10
Fuera[17]:
['吃客云集的小吃街,地道吃食令人回味。',
'专注正宗牛肉面,开放式厨房热气腾腾',
'大众巷是兰州最古老的美食街,拥有许多老字号当地特色美食,是游客体验兰州美食文化的绝佳去处。',
'兰州代表性的小吃店,明档操作干净放心',
'颇具名气的牛肉面馆,当地人的家庭食堂',
'个人觉得安泊尔是我吃过最好吃的牛肉面了,不过这家店的位置很尴尬,只有这趟路线才能涉及到',
'老牌人气甜食店,荣获多个美食奖项',
'店里面的装修环境是非常不错的,有人说价格有点贵,看了一下菜单,相对于夜市上的来说确实有一点贵,...',
'人气爆棚的口碑餐厅,各式烤串喷香诱人',
'当地食堂级别的老店,牛肉面汤清味醇面韧。']
Resultado final del rastreo: exactamente 2000 piezas de datos
El siguiente es un análisis de los dos datos rastreados anteriormente:
Análisis de datos de alimentos
Datos de importacion:
Información básica del campo:
En 3]:
# 1-数据缺失值
df.isnull().sum()
Fuera[3]:
中文名 0
得分 0
均价 0
地址 0
推荐菜 0
评价 0
dtype: int64
En [4]:
# 2、字段类型
df.dtypes
Fuera[4]:
中文名 object
得分 object
均价 int64
地址 object
推荐菜 object
评价 object
dtype: object
Analiza qué tiendas tienen las puntuaciones más altas:
En [5]:
# 得分中有未评分的数据:--
df["得分"].value_counts()
Fuera[5]:
-- 1721
3.5 139
3.0 50
4.0 29
4.5 20
5.0 13
4.3 7
4.2 6
0.0 5
4.1 4
2.0 2
3.8 1
4.7 1
2.5 1
1.0 1
Name: 得分, dtype: int64
En [6]:
# 将未评分的数据统一替换成0.0,也就是0分
df["得分"] = df["得分"].apply(lambda x: x.replace("--","0.0"))
Estadísticas de puntuación
La mayoría de las tiendas tienen una puntuación de 3,5 puntos, que no parece ser muy alta~
Las 10 mejores tiendas
Precio medio de tienda
restaurante de alta gama
Casa de fideos
Cuando llegas a Lanzhou, debes comer fideos: según las estadísticas, hay 284 restaurantes de fideos.
restaurante de olla caliente
Según las estadísticas, hay 129 restaurantes de ollas calientes:
px.bar(huoguo[:15],x="中文名",y="得分")
Estadísticas de alimentos
Nube de word de platos recomendados
Dibuje un diagrama de nube de palabras de platos locales recomendados:
rec_words = [tuple(z) for z in zip(result["词语"].tolist(), result["次数"].tolist())]
# 选择前100个词语
c = (
WordCloud(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
.add("", rec_words[:100], word_size_range=[20, 80], shape=SymbolType.DIAMOND)
.set_global_opts(title_opts=opts.TitleOpts(title="兰州美食词云图"))
)
c.render_notebook()
Análisis de datos de atracción
o importar los datos primero
exploración de datos
En 3]:
df1.shape
Fuera[3]:
(381, 8)
En [4]:
df1.isnull().sum()
Fuera[4]:
cn_title 0
en_title 113
strategy 0
comment 0
location 0
ranking 0
lvyou 0
abstract 351
dtype: int64
Faltan valores en el nombre en inglés de la atracción en_title y en el resumen de la introducción
En [5]:
df1.dtypes
Fuera[5]:
cn_title object
en_title object
strategy int64
comment int64
location object
ranking int64
lvyou object
abstract object
dtype: object
Ubicación de las atracciones
En [6]:
df2 = df1["location"].value_counts().reset_index()
df2.columns = ["location","number"]
df2
Fuera[6]:
ubicación | número | |
---|---|---|
0 | Lanzzhou | 301 |
1 | yong deng | 39 |
2 | Gaolan | veintiún |
3 | yuzhong | 20 |
En [7]:
c = (
Pie(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
.add("", [list(z) for z in zip(df2["location"].tolist(), df2["number"].tolist())])
.set_global_opts(title_opts=opts.TitleOpts(title="兰州景点分布"),
legend_opts=opts.LegendOpts(pos_left="80%", orient="vertical"))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
c.render_notebook()
Número de asaltantes
10 comentarios principales
c = (
Funnel(init_opts=opts.InitOpts(theme=ThemeType.CHALK,
width="800px",
height="500px"
))
.add("兰州景点评论数漏斗", [list(z) for z in zip(df5["cn_title"].tolist(), df5["comment"].tolist())])
.set_series_opts(label_opts=opts.LabelOpts(is_show=True))
)
c.render_notebook()
Nube de word de atracciones
Visualización de las primeras 50 palabras:
rec_words = [tuple(z) for z in zip(result["词语"].tolist(), result["次数"].tolist())]
c = (
WordCloud(init_opts=opts.InitOpts(theme=ThemeType.ROMA))
.add("", rec_words[:50], word_size_range=[20, 80], shape=SymbolType.DIAMOND)
.set_global_opts(title_opts=opts.TitleOpts(title="兰州景点词云"))
)
c.render_notebook()
dibujo general
# 1-景点位置
def piePage() -> Pie:
c = (
Pie(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
.add("", [list(z) for z in zip(df2["location"].tolist(), df2["number"].tolist())])
.set_global_opts(title_opts=opts.TitleOpts(title="兰州景点分布"),
legend_opts=opts.LegendOpts(pos_left="80%", orient="vertical"))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}")))
return c
# 2-攻略数
def barPageOne() -> Bar:
c = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
.add_xaxis(df4["cn_title"].tolist()[::-1])
.add_yaxis("攻略数", df4["strategy"].tolist()[::-1])
.reversal_axis() # 翻转坐标轴
.set_series_opts(label_opts=opts.LabelOpts(is_show=True, position="right")) # 是否显示数据以及label的位置(显示在右方)
.set_global_opts(title_opts=opts.TitleOpts(title="兰州景点攻略数前10"))
)
return c
# 3-评论数
def funnlePage() -> Funnel:
c = (
Funnel(init_opts=opts.InitOpts(theme=ThemeType.MACARONS,
width="800px",
height="600px"
))
.add("兰州景点评论数漏斗", [list(z) for z in zip(df5["cn_title"].tolist(), df5["comment"].tolist())])
.set_series_opts(label_opts=opts.LabelOpts(is_show=True)))
return c
# 4-驴友占比
def barPageTwo() -> Bar:
c = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.WALDEN))
.add_xaxis(df6["cn_title"].tolist())
.add_yaxis("", df6["lvyou_number"].tolist())
# .reversal_axis() # 翻转坐标轴
.set_series_opts(label_opts=opts.LabelOpts(is_show=True)) # 是否显示数据以及label的位置(显示在右方)
.set_global_opts(title_opts=opts.TitleOpts(title="兰州景点驴友占比"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-30)), # 设置旋转角度
))
return c
# 5-词云图
def worldPage() -> WordCloud:
rec_words = [tuple(z) for z in zip(result["词语"].tolist(), result["次数"].tolist())]
c = (
WordCloud(init_opts=opts.InitOpts(theme=ThemeType.ROMA))
.add("", rec_words[:50], word_size_range=[20, 80], shape=SymbolType.DIAMOND)
.set_global_opts(title_opts=opts.TitleOpts(title="兰州景点词云"))
)
return c
page = (
Page(layout=Page.DraggablePageLayout)
.add(
piePage(),
barPageOne(),
funnlePage(),
barPageTwo(),
worldPage()
))
page.render("lanzhou.html")
- Estoy participando en el reclutamiento del programa de firma de creadores de la Comunidad Tecnológica de Nuggets, haga clic en el enlace para registrarse y enviar .