Py学习  »  Python

用 Python 爬取网红城市大长沙!

Python绿色通道 • 2 年前 • 180 次点击  

↑ 关注 + 星标 ,每天学Python新技能




    

后台回复【大礼包】送你Python自学大礼包

这两天获取了两份关于长沙的数据:长沙景点和长沙美食,之后进行了分析,如果有朋友想去长沙或者周边城市玩,要仔细看看喔。

导入库

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, Pie, Line, HeatMap, Funnel, WordCloud, Grid, Page  # 各个图形的类
from pyecharts.commons.utils import JsCode   
from pyecharts.globals import ThemeType,SymbolType

import plotly.express as  px
import plotly.graph_objects as go

长沙景点

数据获取

长沙景点的数据获取方法和之前那篇关于厦门的文章是一样的,只是重新跑了一遍代码,具体过程不再阐述,感兴趣的朋友可以看之前的文章,爬取的字段:

  • 中文名
  • 英文名
  • 攻略数
  • 评价数
  • 位置
  • 排名
  • 驴友占比
  • 简介

具体的源代码如下:

最终数据有1152条,数据中绝大部分是长沙的景点数据,也有少量少量周边城市,比如:宁乡、浏阳等的数据,整体的数据前5行如下:

下面重点介绍数据分析的过程

整体情况

首先看看整体的数据情况:

fig = px.scatter(changsha[:10],  # 前10个
           x="strategy",  # 攻略数
           y="comment",   # 评论数
           color="comment",  # 颜色选取
           size="comment",  # 散点大小
           hover_name="cn_title",
           text="cn_title"  # 显示文字
          )

fig.update_traces(textposition='top center')  # 文本顶部居中显示

fig.show()

很显然:橘子洲、岳麓山、岳麓书院、太平老街排名靠前

排名靠前景点

看看排名靠前的景点是哪些?

# 根据ranking排序取出前20名数据,排除ranking=0的数据,再取出前10数据

changsha1 = changsha[changsha["ranking"] != 0].sort_values(by=["ranking"])[:20].reset_index(drop=True)
changsha1.head(10)

通过排名我们发现:橘子洲(烟火、大桥、天心阁)、岳麓山(书院)、黄兴路步行街、马王堆汉墓遗址、湖南省博物馆,整体排名很靠前,深受游客们欢迎,具体看看排名前20的景点:

评论火爆景点

很多游客到了一个景点喜欢写评论,看下哪些景点获得大量的评论:




    
changsha2 = changsha[changsha["comment"] != 0].sort_values(by=["comment"],ascending=False)[:10]

# 绘图
fig = px.scatter(
    changsha2,
    x="cn_title",
    y="comment",
    size="comment",
    color="comment",
    text="cn_title"
)

fig.update_traces(textposition="top center")

fig.show()

攻略在手,旅游不愁

出门旅游之前最好还是做一份旅游攻略,看看提供攻略最多的前10景点是哪些:

如果我们考虑前20个景点的攻略数:

驴友占比

我们爬取到的驴友数据是百分比,类型是字符串类型,我们现在去掉%符号,取出左边的数值,如果没有则用0代替,方便最终画图,具体操作如下:

# 去掉%取出左边数据
changsha["lvyou_number"] = changsha["lvyou"].apply(lambda x:x.split("%")[0])
changsha["lvyou_number"] = changsha["lvyou_number" ].astype(int)
changsha.head()

取出排名前10的驴友占比景点:

景点介绍

获取到的abstract字段是用来描述景点的基本信息,可以用来制作词云图,具体处理过程如下:

abstract_list = changsha["abstract"].tolist()

# 1、分词
jieba_name = []
for i in range(len(abstract_list)):
    # seg_list只是一个generator生成器:
    seg_list = jieba.cut(str(abstract_list[i]).strip(), cut_all=False)  
    # 对list(seg_list)中的每个元素进行追加
    for each in list(seg_list):   
        jieba_name.append(each)
       
# 2、去停用词
# 创建停用词list
def stopwordslist(filepath):
    stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
    return stopwords

# 传入路径,加载去停用词
stopwords = stopwordslist('/Users/peter/Desktop//nlp_stopwords.txt')  

stopword_list = []
for word in jieba_name:  # jieba_name中的word不在停用词表中,且不是\t制表符
    if word not in stopwords:
        if word != "\t" and word != " " and word != "nan":
            stopword_list.append(word)
            
# 3、统计单词出现个数
dic = {}
number = 0

for each in stopword_list:
    if each in dic.keys():
        number += 1   
        dic[each] = number
    else:
        dic[each] = 1 # 不存在则结果为1

# 4、字典转成json数据,绘制词云图需要
tuple_list = []
for k,v in dic.items():
    tuple_list.append(tuple([k,v]))
    
tuple_list[:20]

长沙美食

第二部分介绍的是长沙(附近部分长沙)的美食,接下来从3个方面介绍:

  • 字段获取
  • 数据保存及处理
  • 美食数据分析

发送请求

url = "https://travel.qunar.com/p-cs300022-changsha-meishi?page=1"

headers = {"user-agent""个人请求头"}

response = requests.get(url=url,headers=headers)
result = response.content.decode()

字段获取

  • 名称cn_title
  • 评分socre
  • 均价person_avg
  • 地址address
  • 推荐菜recommand
  • 评价comment

1、源码结构

网页显示每页有10个景点(最后页未必是10个),总共200页的数据,每个景点的信息包括在一个

  • 标签对中,我们只需要从标签中获取到相应的信息即可

    2、名称和评分两个字段的获取相对简单,直接通过正则表达式来获取,关键字定位需要准确(以后会详细详解正则表达式的使用)

    
    
    
        
    # 中文名
    cn_title = re.findall('cn_tit">(.*?).*?countbox',result,re.S)
    # 得分:没有得分用--表示
    score = re.findall('cur_score">(.*?).*?total_score',result,re.S)

    3、关于剩下4个字段的获取,相对复杂。因为他们并不是在每个店的信息中存在,有的,但是他们有一个共同点:全部是隐藏一个

    标签对中,而且每个字段都有自己的关键词

    具体处理方法:先大后小

    1、先整体:提取sublistbox下面的全部信息

    2、从步骤1的信息进行判断,获取4个单独字段

    # 均价
    person_avg = []

    for i in range(len(sublistbox)):
        try:
            if "均" in sublistbox[i]:  # 如果均价存在
                person_avg.append(re.findall('¥ (.*?)',sublistbox[i],re.S)   [0])   # 将解析出来的第一个字段放入列表中
            else:  # 否则,不存在的话,添加0
                person_avg.append(0)
            continue   # 遇到报错继续往下执行
        except:
            person_avg.append(0)

    剩下3个字段处理类似:

    address = []

    for i in range(len(sublistbox)):
        try:
            if "址" in sublistbox[i]:  # 关键词
                address.append(re.findall('址.*?des_line">(.*?)',sublistbox[i],re.S)[0])
            else:
                address.append("无")
            continue
        except:
            address.append("无")
    recommand = []

    for i in range(len(sublistbox)):
        try:
            if "推荐菜" in  sublistbox[i]:
                recommand.append(re.findall('推荐菜.*?des_line">(.*?)',sublistbox[i],re.S)[0])
            else:
                recommand.append("无")
            continue
        except:
            recommand.append("无")
    comment = []

    for i in range(len(sublistbox)):
        try:
            if "desbox" in sublistbox[i]:   # 关键词
                comment.append(re.findall('.*?txt">(.*?)',sublistbox[i],re.S)[0])
            else:
                comment.append("无")
            continue
        except:
            comment.append("无")

    4、上面是获取单页数据的解析过程,下面讲解如何获取200页的字段数据:

    # 中文名:得分字段类似
    cn_title_list = []

    for i in range(1,201):
        url = "https://travel.qunar.com/p-cs300022-changsha-meishi?page={}".format(i)
        headers = {"user-agent" "请求头"}
        response = requests.get(url=url,headers=headers)
        result = response.content.decode()
        cn_title = re.findall('cn_tit">(.*?).*?countbox',result,re.S)
        for each in cn_title:
            cn_title_list.append(each)
            
    cn_title_list
    #  均价字段:地址、推荐菜、评价类似
    # 某个字段不存在,用0或者无代替
    person_avg_list = []

    for i in range(1,201):
        url = "https://travel.qunar.com/p-cs300022-changsha-meishi?page={}".format(i)
        headers = {"user-agent"""}
        response = requests.get(url=url,headers=headers)
        result = response.content.decode()
        
        # 1、先整体提取
        sublistbox = re.findall('sublistbox">(.*?)
  • Python社区是高质量的Python/Django开发社区
    本文地址:http://www.python88.com/topic/120465
     
    180 次点击