Python爬取斗鱼英雄联盟所有玩adc的主播房间信息并用redis存储数据
最近想要用巩固下json数据的提取以及数据的存储,于是选了斗鱼作为研究对象。。
下面就是所有要爬取的adc,当然有个别adc没人玩就不爬不了。
首先观察下虚空之女和赏金猎人这两个英雄的直播页面什么差异。
可以发现,两者的url并没有差异,那么就不能从html页面下手了,接下来再看看XHR和json。
在XHR的getTagRoomlist中发现了直播间相关的数据
然后再观察Headers中的内容
这是虚空之女的直播间页面url:
https://www.douyu.com/dir_new/getTag2RoomList?tag2_id=247&page=1&cate2_id=1
然后下面是赏金猎人的:
https://www.douyu.com/dir_new/getTag2RoomList?tag2_id=241&page=1&cate2_id=1
可以发现他们仅有tag2_id不同。那么只要获取到这个id的list就能请求相关的数据了。但是观察了一下左边这一栏所有的内容都没有发现和英雄对应的id有关的信息。
折腾了一会发现要重新刷新当前页面才能看到id的信息,也就是不进行任何筛选的情况下才能看到。
所有的tag_id都在第一个url中:https://www.douyu.com/dir_new/getAllTag1withtag2list?cate2_id=1
那么思路就是先请求这个url获取所有的英雄对应的id,然后根据id组建新的url,再各个请求,获取信息。
首先导入必要的包,最后数据存储用redis(最近学的这个,后续还会更mySQL)
import requests
import redis
base_url = 'https://www.douyu.com/dir_new/getAllTag1withtag2list?cate2_id=1' # 用来请求id的url
room_url = 'https://www.douyu.com/dir_new/getTag2RoomList?tag2_id={}&page=1&cate2_id=1' #待拼接的url
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'
}
获取英雄的id
def get_id():response = requests.get(base_url, headers=headers)#观察json中的格式结构进行提取info = response.json()['data'][4]['tag2_list']return info
最后返回的就是它,一个list,后面只需要循环提取就ok。
获取房间信息
def get_room_info(hero_id, hero_name):url = room_url.format(hero_id)response = requests.get(url, headers=headers)#仅提取其中的room_list信息room_info = response.json()['data']['room_list']total_room = []for item in room_info:each_room = dict()each_room['room_id'] = item['rid'] #房间ideach_room['room_name'] = item['rn'] #房间名each_room['room_host'] = item['nn'] #主播each_room['hero_name'] = hero_name #英雄名称# 把room的信息合并成一个字典total_room.append(each_room)return total_room
主程序
包括函数的调用以及数据的存储
#调用函数获取id
info = get_id()
#调用redis数据库
client = redis.StrictRedis(host='XXX.X.X.X', port='6379')
for item in info:hero_id = item['tag2_id'] #获取英雄idhero_name = item['tag2_name'] #获取英雄名称#调用函数获取room信息hero_room = get_room_info(hero_id, hero_name) #由于某些英雄没有主播在玩,也就没有room信息,所以要判断一下获取的hero_room是否为空if hero_room != '':#由于字典不支持迭代,所以将其转化为list类型再进行迭代hero_room = list(hero_room)for ind, hero in enumerate(hero_room):#作为哈希数据写入redis,每一个直播间作为一个fieldclient.hmset(hero_name+str(ind), {'room_id': hero['room_id'], 'room_name': hero['room_name'], 'room_host': hero['room_host']})
最后测试一下是否导入成功
import redis
client = redis.StrictRedis(host='127.0.0.1', port='6379')
print(client.hget('寒冰射手1', 'room_id'))返回
b'7153773'
Bingo!