美文网首页
爬虫眼中的“周庄”长什么样?

爬虫眼中的“周庄”长什么样?

作者: 山阴少年 | 来源:发表于2018-09-20 15:04 被阅读30次

  本次爬虫项目将会爬取携程网中关于“周庄古镇”的点评,然后对这些评论进行中文分词及预处理,形成一张关于“周庄古镇”的词云图,得到可视化的分析结果。

项目介绍

  马上要到中秋啦,正好这几天在公司不太忙,想着中秋假期即将去周庄旅游,于是,笔者心血来潮地想到,能不能利用爬虫做一些关于周庄的分析呢?琢磨许久,笔者终于有了思路,因此,本次爬虫的大致思路是这样的:

  • 获取数据: 利用爬虫爬取携程网中关于周庄的点评
  • 文本预处理:对这些评论进行中文分词以及预处理
  • 可视化分析: 制作词云图并分析

  整个项目的结构如下:

项目结构

其中,两个Python文件分别为爬虫文件和文本预处理及制作词云图文件,zhouzhuang.csv为爬取的评论文件,zhouzhuang.txt为结巴分词时添加的词语文件,simsun.ttc为制作词云图时的字体文件(为了能在词云图中正确地显示中文,你需要这个字体文件)。

爬取携程中的评论

  首先我们需要获取数据,即关于周庄的点评。笔者选取携程网中对“周庄古镇”的点评作为项目的数据集,具体网址为:http://you.ctrip.com/sight/zhouzhuang81/109861-dianping.html 。该网页一共有8285条点评,共分415页展示,每页20条评论,评论有长有短,也有图片,我们只需要评论中的文字部分。如下图所示:

携程网上关于周庄的评论

  接下来,笔者利用Python爬取这些网页中评论,完整的Python代码(zhouzhuang_comments_scrape.py)如下:

import requests
import pandas as pd
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED

# 评论列表
comments = []

# 提取评论,传入参数为网址url
def get_comment(url):

    global comments

    try:
        # 发送HTTP请求
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 \
                             (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'}
        r = requests.get(url=url, headers=headers)

        # 解析网页,定位到评论部分
        soup = BeautifulSoup(r.text, 'lxml')
        main_content = soup.find_all('div', class_='comment_single')

        # 提取评论
        for para in main_content:
            comment = para.find('span', class_='heightbox')
            print(comment.text)
            comments.append(comment.text.replace('&quot', ''))

    except Exception as err:
        print(err)

def main():
    # 请求网址(共415个网页)
    urls = ["http://you.ctrip.com/sight/zhouzhuang81/109861-dianping-p%d.html"%x for x in range(1,416)]
    urls[0] = urls[0].replace('-p1', '')

    # 利用多线程爬取景点评论
    executor = ThreadPoolExecutor(max_workers=20)  # 可以自己调整max_workers,即线程的个数
    # submit()的参数: 第一个为函数, 之后为该函数的传入参数,允许有多个
    future_tasks = [executor.submit(get_comment, url) for url in urls]
    # 等待所有的线程完成,才进入后续的执行
    wait(future_tasks, return_when=ALL_COMPLETED)

    # 创建DataFrame并保存到csv文件
    comments_table = pd.DataFrame({'id': range(1, len(comments)+1),
                                   'comments': comments})

    comments_table.to_csv(r"./ZhouZhuang/zhouzhuang.csv", index=False)

main()

在这个爬虫中,我们利用了concurrent.futures这个模块中的多线程来加速爬取评论,同时将这个评论储存在pandas中的DataFrame中,最后将这些评论保存为zhouzhuang.csv文件,便于后续的文本预处理。zhouzhuang.csv文件的内容如下:

zhouzhuang.csv文件内容(部分)

  事实表明,该网站虽然写着有8285条评论,但csv文件中却只有3020条评论,而且笔者自己也验证了以下,大概200页之后的网站确实也没评论了,难道需要其它操作?Anyway,3千多条评论足够了。

文本预处理

  在这部分,我们只是讲解文本预处理的操作流程,并不会给出Python代码,Python代码会在后续的“制作词云图”部分一起给出,作为一个完整的Python文件。
  文本预处理的流程如下:

  • 利用Pandas读取评论的csv文件(zhouzhuang.csv);
  • 对该csv文件中的每一条评论,先进行中文分词处理(带有词性标注),然后去掉特殊字符和标点符号,再去掉常用的停用词(stopwords);
  • 对评论中的名次及词性为“非语素字” 的词语进行词频统计。

  我们给出在中文分词过程中用到的用户自己添加的词语,即zhouzhuang.txt中的词语,如下:

江南水乡
江南第一水乡
沈万三
周庄
苏州
昆山
纸箱王主题创意园区
纸箱王
双桥
沈万三故居
沈厅
古戏台
张厅
四季周庄
周庄南湖
富安桥
迷楼
怪楼
贞丰桥
逸飞之家
生命奥秘博物馆
贞丰文化街
台湾老街
沈万三水冢
太平桥
全福讲寺
澄虚道院
周庄舫
叶楚伧故居
牌楼塔影
爱渡风情小镇
源丰顺酒作坊
白蚬湖
周庄博物馆
戴宅
福洪桥
万三水上财道游
古镇水巷游
南湖秋月园
全福塔
全福长桥
蚬江渔唱馆
蜡工坊名人蜡像馆
画家村
大诚堂
亲亲鱼鱼疗馆
太史淀
周庄绿乐园
大吉祥文化馆
周庄魔城
云海塔
周庄富贵园
永庆庵
舟际皮划艇俱乐部
英伦骑士马术俱乐部
网咖
江南第一水乡
万三蹄髈
朱元璋
5A级景区
北宋
元祐元年
万三蹄
江南六大古镇
完美
月圆之夜
5A级景区
万三
平江路
山塘街
同里
万历年间
万历
乌镇
第一水乡
打call
5A级旅游景区
5A景区
陈逸飞

制作词云图

  接下来就是最后的制作词云图部分了,在这儿,我们可以得到关于“周庄古镇”的评论的可视化结果。
  需要注意的是,你的Python中需要安装wordcloud模块,同时,为了能在词云图中正常地显示中文,需要添加一下中文字体库。具体的制作过程不再详述,笔者这里只给出最简单的词云图绘制。
  完整的Python代码(comments_anlysis.py)如下

# -*- coding: utf-8 -*-
import jieba.posseg
import pandas as pd
from collections import defaultdict
import matplotlib.pyplot as plt
from wordcloud import WordCloud

# 词频统计字典
dic = defaultdict(int)

# 对每条评论进行分词及预处理
def cut_word(sentence):

    # 去掉句子中的特殊字符及标点符号
    sentence = sentence.replace('&quot', '').replace('\n', '')
    biaodian_list = '~!@#¥%……&*()【】{}:;‘’“”《》,。、? -_,./<>;:\'"!$^()  ヾ?~≈′'
    for biaodian in biaodian_list:
        sentence = sentence.replace(biaodian, '')

    # 分词(带词性标注)
    words = jieba.posseg.cut(sentence)

    # 常用词
    stop_words = ['的', '我', '你', '他', '她', '它', '我们', '你们', '他们', '她们', '它们', \
                  '这', '这儿', '那', '那儿', '在', '在哪', '这里', '哪里', '那里', '了', '吗','啊', \
                  '是', '不是', '着', '谢谢', '也', '就', '去', '到', '可以', '不', '什么', '会', \
                  '再', '哦', '有', '很', '都', '和', '还是', '还', '感觉', '上', '但', '来',\
                  '一个', '地方', '就是',  '里面', '一次', '一些', '这次', '已经', '又', '个', '这个', \
                  '那个', '要', '但是', '里', '看', '住', '让', '太', '没', '说', '时候',\
                  '小', '大', '还有', '走', '不过', '比较']

    # 只统计名词或词性为x的词语
    for word in words:
        # 去掉句子中的常用词
        if word.word not in stop_words:
            # 判断是否为名词
            if 'n' in word.flag or 'x' in word.flag:
                word = word.word # 取出该名词
                print(word)
                dic[word] += 1

def main():

    jieba.load_userdict(r'./Zhouzhuang/zhouzhuang.txt')

    # 读取评论csv文件并进行分词,预处理,统计词频操作
    df = pd.read_csv(r'./Zhouzhuang/zhouzhuang.csv', encoding='utf-8')
    df['comments'].apply(lambda x: cut_word(x))

    # 对词语进行排序
    sort_dict = sorted(dic.items(), key=lambda x: x[1], reverse=True)
    # print(sort_dict)
    wl_space_split = []
    for i in range(40):
        print(sort_dict[i])
        for _ in range(sort_dict[i][1]):
            wl_space_split.append(sort_dict[i][0])

    # 产生词云图并显示
    my_wordcloud = WordCloud(font_path=r"./Zhouzhuang/simsun.ttc", background_color='white')\
                            .generate(" ".join(wl_space_split))

    plt.imshow(my_wordcloud)
    plt.axis("off")
    plt.show()

main()

  最高频的40个词语如下:

('周庄', 2375)
('古镇', 1187)
('人', 1113)
('小桥流水', 466)
('门票', 456)
('江南', 456)
('景区', 454)
('水乡', 416)
('江南水乡', 372)
('景点', 358)
('人家', 337)
('景色', 287)
('沈厅', 261)
('商业', 252)
('中国', 250)
('商业化', 244)
('特色', 243)
('万三蹄', 215)
('风景', 205)
('建议', 194)
('气息', 193)
('美', 192)
('双桥', 188)
('第一水乡', 179)
('有点', 178)
('小镇', 176)
('味道', 172)
('苏州', 171)
('乌镇', 169)
('客栈', 165)
('张厅', 161)
('导游', 148)
('生活', 147)
('建筑', 147)
('时间', 145)
('游玩', 143)
('沈万三', 142)
('文化', 140)
('夜景', 139)
('游客', 139)

产生的词云图如下:

“周庄”词云图

自己的分析

  嗯,好不容易用自己的方法得到了可视化的结果,即上述的词云图,那么,对笔者的中秋之旅会有什么建议呢?

  1. 周庄是个古镇,江南水乡,小桥流水,风景应该很不错。所以,在旅游的过程中,要欣赏景色,也许夜景也是不错的。
  2. 周庄的很多景点及特色也在词云图中有展示,如沈厅,张厅,双桥,万三蹄等,那么,在旅游的过程中,这些事物是不该错过的。
  3. 也有很多人对商业化提出了看法,也许,中国的古镇商业化确实太严重了,搞得所有的古镇都是一个样子,少了很多趣味。
  4. 至于词云图中为什么没有出现“人”,“美”等词语,这是可以打一个问号的。

项目总结

  本次爬虫项目,爬取了携程网中关于“周庄古镇”的点评,然后对这些评论进行中文分词及预处理,形成一张关于“周庄古镇”的词云图,得到笔者自己的一些分析结果。当然,我们能做的还有很多,比如对评论中提到的景区进行统计,绘制景点提到频数直方图等。
  所谓爬虫,其意义在于为数据建模提供数据,因此,对于数据分析和建模来说,爬虫只是万里长征的第一步。当然,爬虫也可以做很多有意义的事情,那么,你有哪些有意思的项目呢?欢迎交流哦~

  本次爬虫项目仅作为笔者的练手项目,并不作为商用。如有转载或商用,请及时联系笔者,谢谢~
  提前祝大家中秋节快乐~

注意:本人现已开通微信公众号: 轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

相关文章

  • 爬虫眼中的“周庄”长什么样?

      本次爬虫项目将会爬取携程网中关于“周庄古镇”的点评,然后对这些评论进行中文分词及预处理,形成一张关于“周庄古镇...

  • 乡村振兴典范案例:周庄云谷田园

    周庄云谷田园是中国首个“物联网+田园”智慧社区,周庄转型新的动力核心型乡村旅游发展的标杆。未来科技田园是什么样子?...

  • 我眼中的诗长什么样

    我 没有华丽的辞藻 没有波涛汹涌的感情 没有惊世骇俗的见解 我 只有平凡的文字 只有波澜不惊的感情 只有不愿随波逐...

  • 你眼中的干货长什么样?

    我们经常在文章看到这样一个词,叫做“干货”。什么叫做干货呢?我问过很多人,如果让他们具体的下一个定义,他们可能下不...

  • 梦游周庄

    1.每个人都生活在幻想之中。 2.这几天我一直在规划想去周庄转一转,看看传说中的周庄到底是什么样子。 3.我对周庄...

  • 我眼中的幸福,是长什么样子?

    文/无二师兄 哲学家费尔巴哈说“你的第一责任是使你自己幸福。你自己幸福,你也就能使别人幸福。” 那么到底什么是幸福...

  • 在读者眼中,好文长什么样?

    今天看了《为何爱会伤人》,前半部分我看得那个津津有味呀:“写得太好了!”但后半部分,我就不太看得进去,匆匆翻完了。...

  • 中国诗肖像第二十六季入围参选人044

    ·周庄 刘道远 水是周庄的脸 周庄是水的骨头 周庄的谜写在水上 半颗月亮 落户周庄 給丟失半颗心的问道人摆渡 周庄...

  • 倒影里的周庄

    周庄的桥,周庄的水,周庄的景,周庄的人……都在倒影里。 倒影里的周庄是多么安静神秘,这是来自天上的最高处而映落入人...

  • 周庄!周庄!

    小桥流水人家,当年在课本里学的文章,在我的第二十二个人生时终于体会到了,这也是我第一次和我的女朋友一起来一场说走就...

网友评论

      本文标题:爬虫眼中的“周庄”长什么样?

      本文链接:https://www.haomeiwen.com/subject/bgcnnftx.html