python使用requests爬取DOTA2轮盘数据

写在前面

本文主要概述如何爬取DOTA2的轮盘(chatwheel)数据,以便后期对轮盘数据结合其他数据做数据可视化&数据分析。

环境配置

环境为python3.6,需安装requestspandasbeautifulsoup等库

数据类型

查阅大量的资料,我归总DOTA2的轮盘数据为以下3类:

  1. 普通的轮盘,例如Well played!Missing! 等基础轮盘语音
  2. 勇士令状语音轮盘,如Patience from Zhou啊,队友呢?队友呢?队友呢?!队友呢?!?! 等经典解说语录轮盘
  3. 英雄轮盘,例如等英雄特有的轮盘

确定好轮盘的类型后,就要确定每个轮盘的ID,查阅资料发现规律如下:

  1. 普通轮盘,勇士令状轮盘:ID范围在0~234
  2. 英雄轮盘: 英雄ID+轮盘索引,举个例子,亚巴顿(英雄编号为102)的第一条语音轮盘为Link▶️ Ha ha ha ha ha ha ha ha ha.,所以这条语音的ID为102001

我们现有的资源如下:

  • Dota 2 Wiki(基本数据)Dota 2 Wiki链接
  • opendota(查找英雄ID)opendota链接

流程图

画个流程图,防止看晕

内容+ID
内容+ID
内容+英雄名称
英雄名称+ID
Dota 2 Wiki
普通轮盘
勇士令状轮盘
英雄轮盘
opendota

爬取数据

1. 普通轮盘,勇士令状轮盘:

因为Dota2 wiki网页是静态的,很好爬,所以可以直接通过requests请求轮盘数据的地址。
打开网页可以很直观看到普通轮盘和勇士令状轮盘还是有点区别,所以:

  • 普通轮盘:爬取Phrase,Console command
  • 勇士令状轮盘:爬取Lines,Console command
    python使用requests爬取DOTA2轮盘数据_第1张图片
    简述一下爬取思路:
  1. CSS 搜索类名'wikitable',即 soup.find_all(class_= 'wikitable'):可找到所有的数据。
  2. 轮盘每列的数据标签都是td,所以判断子标签td的个数,若为3,则是普通轮盘,若为4则是勇士令状轮盘
  3. 对于勇士令状轮盘,多个数据在一行里,这里直接暴力爬取后两列数据,前一半为内容,后一半为ID

核心代码如下:

re = requests.get(r'https://dota2.gamepedia.com/Chat_Wheel')
soup = BeautifulSoup(re.text,'html.parser')
df_list = []
for i in soup.find_all(class_= 'wikitable'):
    chat_df = pd.DataFrame(columns = ['Phrase', 'Console command'])
    for index, tr in enumerate(i.find('tbody').children):
        if isinstance(tr, bs4.element.Tag):
            if index != 0:
                if (tr('td')[1].string != None) and (len(tr('td')) == 3):
                    chat_df = chat_df.append(pd.DataFrame({'Phrase':[tr('td')[0].text], 
                                                       'Console command':[tr('td')[1].text]}), ignore_index = True)
                else:
                    chat_list = []    
                    for a in tr.find_all('li'):
                        chat_list.append(a.text)
                    command = chat_list[:int(len(chat_list)/2)]
                    Phrase = chat_list[int(len(chat_list)/2):]
                        
                    chat_df = chat_df.append(pd.DataFrame({'Phrase':Phrase, 
                                                           'Console command':command}), ignore_index = True)
    df_list.append(chat_df)

这时数据已经在df_list中,其中每个索引的数据即为Dota wiki上按顺序出现的每个数据块,具体如下:

  • 基础轮盘:0~7
  • 2017_Audio :8 ,2018_Audio:9 ,2018_spary:10 ,2019_Audio:11 ,2019_spary:12,其中每一年新更新的勇士令状轮盘会包含前几年的,所以我们只需要2019_Audio和2019_spary
# base:0,7 2017:8 2018:9 2018_spary:10 2019:11  2019_spary:12

for i in [0,1,2,3,4,5,6,7,11,12]:
    if i == 0:
        chat_df_all = df_list[i]
    else:
        chat_df_all = pd.concat([chat_df_all, df_list[i]], ignore_index = True)

之后再提取标签id,排序,即可得最终的普通轮盘,勇士令状轮盘数据,最后数据共183条,部分如下:
python使用requests爬取DOTA2轮盘数据_第2张图片

2. 英雄轮盘:

需要爬取的英雄轮盘如下:
python使用requests爬取DOTA2轮盘数据_第3张图片
这个的爬取思路和上面的类似,不再赘述。
现在我们需要从opendota上找到每个英雄名字所对应的英雄ID,查阅了opendota文档后,'https://api.opendota.com/api/heroes'这条api可获取所有英雄的属性,包括对应的ID。于是我们可以得到一个新的数据表,之后我们将这两个表合并后,便是最终的英雄轮盘数据,共961条,部分如下:

python使用requests爬取DOTA2轮盘数据_第4张图片
最后,对于两个表我们只选中PhraseID部分合并,得到我们最终的轮盘数据,方便后面使用。

你可能感兴趣的:(爬虫)