python3爬虫-获取nga游戏测评关键词词云

0.被血源狂虐的我决定出来报复社会了

1.思路
从主页的所有游戏中获取各游戏的详细测评页面
打开主页面后:
①找到这个游戏所属的平台(后来采用了一种很捷报蛋疼的方法,好在电脑任劳任怨什么都帮我干了
②游戏名称
③游戏的各种评价
④网站自动算出的游戏评分
#或许还应该搞个排名?
#有点内容的比如说新游戏排名,类别排名
⑤游戏发售的时间
把上述内容存入dict中以便查阅
整理数据后提取所有评论,存入一个txt中

21
首先我们要整理一下这些属性的关系:
从首页提取的信息大概遵循这样的规则
game,ps4,8.0,2017-1-1
game,steam,8.0,2017-1-1
game1,switch,9.0,2017-1-2
........
游戏的名字只有一个,发售时间和评分也只有一个,但是平台却不是只有一个。我们所要做的就是把游戏时间评分绑定在一起,用set()去掉重复的部分同时,还要把平台叠加起来。……然后就可以发现这操作起来很麻烦。那怎么办呢,自然是在获取信息的时候就进行筛选,筛选完了再放进去。

platform_list=['ps4','xbox one','Switch','Steam','ios','android','客户端游戏']        
def get_platform(number):
    return platform_list[int(number)-1]

由于在游戏页面中显示平台的那个标签没什么特点,只能用nga分类游戏时记录了,它本身的界面就是http://game.nga.cn/all?platform=1这样格式的。(其中1代表ps4,2表示xbox以此类推)

搞定了这个游戏分类的难题后,就正式开始爬数据。7个平台的游戏下又有分页面,就简单用for循环遍历获取所有数据。

gamedict={}
for url_platform in ['http://game.nga.cn/all?platform={}'.format(i) for i in range(1,8)]:
     for pages in [url_platform+'&page={}'.format(i) for i in range(1,20)]:
        listsoup=BeautifulSoup(requests.get(pages,proxies=proxies,headers=headers).content,'lxml')
        if listsoup.find('div', class_='noItem')==True:
            break
        for game in listsoup.find_all(target='_blank',class_=''):
            name = game.get_text()
            platform = get_platform(url_platform[-1])
            score = game.parent.find_next_sibling('div',class_='num').get_text()
            time = game.parent.find_next_sibling('div',class_='time').get_text().strip('发售')
            url = game.get('href')

这里必须要赞美一下伟大的beautifulsoup模块,也太好用了吧。
nga的结构是这个样子的:

<div class="blockItem addBorder">
    <a class="pic" href="http://bbs.nga.cn/read.php?tid=12852020" style="background-image: url(http://img.nga.cn/attachments/mon_201711/15/-6oh25Q5-58wK1dT3cSi3-9i.jpg);" target="_blank"></a>
    <h5><a href="http://bbs.nga.cn/read.php?tid=12852020" target="_blank">一起剪纸吧 加强版</a></h5>
    <div class="time">2017-11-10<font>发售</font></div>
    <div class="tags"><span class="icon03"></span></div>
    <div class="num">8.1</div>
</div>

如果我们用soup.find_all(target='_blank')找这个tag的话,(我以为)并不能直接找到和它parent tag并列的class='time'或者'num'的那几个tag。
然而BeautifulSoup真是太棒了,它不但提供了找到父标签的方法,还提供了找到兄弟标签的方法,分别是:
tag.parent
tag.find_next_sibling()
这样一来不管目标网页的结构有多混乱都可以轻松找到想获取的内容。


            if (name in gamedict)==True:
                gamedict[name][1].append(platform)
            if (name in gamedict)==False:
                gamedict[name]=[name,list([platform]),score,url,time]  

最后几行if判断干的事情就是烦恼了很久的多平台游戏分类,其实原理也是相当朴素啊……这故事是不是告诉我们整理东西要越早越好(强行大道理)。

2.2
之后我们要做的就是,将从主页爬到的各个游戏的数据进一步扩展,得到详细测评的内容。

comment_pattern=re.compile('postcontent[0-9]')   
#标签的class都是'postcontent+数字'格式     
for info in gamedict.values():
    page=requests.get((info[3]),proxies=proxies,headers=headers).content
    soup=BeautifulSoup(page,'lxml')
    last_page=soup.find('a',class_=' uitxt1')
    #看有没有多页评论进行条件分歧
    if last_page==None:
        cmts=[cmts.get_text() for cmts in soup.find_all(id=comment_pattern,class_="postcontent ubbcode" )][1:]
        cmts_1=[]
        for cmt in cmts:
            cmts_1.append(re.sub('((\[.*\])|(\n)|(\s+))','',cmt))
        info.append(cmts_1)
        
    else:
        for son_page in [info[3]+"&page={}".format(i) for i in range(1,int(last_page_number=last_page.get('href')[-1]))]:
            son_page_soup=BeautifulSoup(son_page,'lxml')
            cmts=[cmts.get_text() for cmts in son_page_soup.find_all(id=comment_pattern,class_="postcontent ubbcode" )][1:]
            cmts_1=[]
            for cmt in cmts:
                cmts_1.append(re.sub('((\[.*\])|(\n)|(\s+))','',cmt))
            #去掉一些空格、换行或者格式为[一些奇怪的字符]的论坛表情代码
            info.append(cmts_1)

2.3
在1.2中我们得到一个格式为
{'游戏名称':'游戏名称',['平台1','平台2','平台3'],'评分','发售日期',['评论1','评论2','评论3','评论4']}
的dict。
(此处有一个疑问,如果取消dict用Class Game(object)存取数据的话会不会更好?但是游戏名称是中文,怎么定义名称又是一个问题。如果有人能解答就好了)
那么我们就可以把comment存到txt中方便存取操作。这一步还算简单。

for info in gamedict.values():
    name=re.sub('((\s+)|(\/))','_',info[0])

这一步就是去除一些windows文件名中非法字符的部分。

    for comment in info[5]:
        comment_txt_file=open('C:\\piyan\\nga_game_comment\\%s.txt'% name,'a',encoding='utf-8')

        print(comment,file=comment_txt_file)
        comment_txt_file.close()

2.4
数据都准备好了,下面就是激动人心的可视化环节辣!!
因为研究到这里已经很累了(是你太菜),就迫不及待地用垃圾效率搞了起来。
分词用的是结巴分词,安利一下:
https://github.com/fxsjy/jieba

特别要提到的是中文会出现方框的情况下,只要设置一下font_path参数就好。

import jieba
from wordcloud import WordCloud,STOPWORDS
import re
import matplotlib.pyplot as plt
font=r'C:\Windows\Fonts\msyh.ttc'
text=open('C:\\piyan\\nga_game_comment\\星露谷物语.txt',encoding='utf-8').read()
text=' '.join(jieba.cut(text,cut_all=True))
wordcloud=WordCloud().generate(text)
STOPWORDS=set(STOPWORDS)
newstopwords=['以为','游戏','真的','不是','可以','非常','系列','还是','这个','虽然','这个','的确','似的','出现','我们','这款','过不去','不多','多个','作为','觉得','差不多']
#其实应该是有词典的吧??但是我懒得研究了就……
for words in newstopwords:
    STOPWORDS.add(words)

wordcloud = WordCloud(max_font_size=200,font_path=font,width=1500,height=800,stopwords=STOPWORDS).generate(text)
plt.figure()
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
wordcloud.to_file('C:\\piyan\\nga_comment_pic\\stardew.png')

我们看一下结果就是


stardew.png

当然如果略过分词阶段效果也挺搞笑的:


watchdog2_full.png
witcher3.png

3.总结
3.1关于数据本身
感觉nga的评分系统也是最近才出的,基数太小本来也就没什么普遍性。下次得试试steam商店的测评,感觉会比较有意思。(问题来了,steam商店没有评分只有好评差评,而且动态页面,至今还没找到那个json文件)
在自己玩的时候(筛选9分以上的ps4游戏),发现,嗯?为什么没有巫师3这不科学?……之后看了一下才知道原来ps4上的叫巫师3年度版之类的,评论的人很少。
那么问题来了,如何把游戏本体和dlc分类到一起,避免这种情况呢?感觉这似乎变成了nlp问题……瑟瑟发抖。
3.2最后说句废话
急需下一个project给我打发时间。这些本质上就是文字的就不够好玩也不够有技术,很愁(没有)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,983评论 4 60
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • This article is a record of my journey to learn Game Deve...
    蔡子聪阅读 3,743评论 0 9
  • # 一度蜜v3.0协议 --- # 交互协议 [TOC] ## 协议说明 ### 请求参数 下表列出了v3.0版协...
    c5e350bc5b40阅读 639评论 0 0
  • 我郁闷了很久,每次想RM, MV操作对应的文件夹,都会收到系统反馈,operation not permitted...
    喵在野阅读 158评论 0 0