一、需求
爬取斗鱼直播网站信息,如直播名字、主播名字、热度、图片和房间网址,将这些数据保存到csv文件中,并单独创建文件夹保存图片。
斗鱼直播网址:https://www.douyu.com/g_LOL
二、分析url
先单击【直播】,然后单击分页,发现分页的时候url没发生变化,基本可以确定是通过异步加载
的。
现在找到了异步url。
此时,可以直接向url发送请求后去数据,还可以使用selenium获取加载之后的网页总数据,提取。
三、数据提取
有两种办法可以选择:
(1)如果使用ajax异步url,就是json转字典。
(2)如果使用selenium,使用xpath提取html数据。
四、代码实现
import requests
import csv
import time
import random
import os
base_url = "https://www.douyu.com/gapi/rkc/directory/mixList/0_0/{}"
headers = {
'accept': 'application/json, text/plain, */*',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cookie': 'dy_did=5cbce4bf40d16268812d1ca500011601; acf_did=5cbce4bf40d16268812d1ca500011601; Hm_lvt_e99aee90ec1b2106afe7ec3b199020a7=1602166389,1602232258; Hm_lpvt_e99aee90ec1b2106afe7ec3b199020a7=1602289306',
'referer': 'https://www.douyu.com/directory/all',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
'x-requested-with': 'XMLHttpRequest'
}
def parse_json(url, params={}):
"""解析url,得到字典"""
time.sleep(random.random())
response = requests.get(url=url, headers=headers, params=params)
return response.json()
def parse_content(url, params={}):
"""解析url,得到字节"""
time.sleep(random.random())
response = requests.get(url=url, headers=headers, params=params)
return response.content
def get_data(url):
"""获取数据"""
data = parse_json(url)
data_list = data["data"]["rl"]
for data in data_list:
item = {}
item["name"] = data["rn"]#直播名字
item["anchor"] = data["nn"]#主播名字
item["hot"] = data["ol"]#热度
item["pic"] = data["rs16"]#图片
item["url"] = "https://www.douyu.com"+data["url"]#房间网址
save(item)
save_pic(item)
def save(item):
"""将数据保存到csv中"""
with open("./斗鱼直播.csv", "a", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(item.values())
def save_pic(item):
"""保存图片"""
# 创建文件夹
if not os.path.exists("./files/douyu"):
os.makedirs("./files/douyu")
#获取字节
content = parse_content(item["pic"])
# 文件的名字
filename = "./files/douyu/{}".format(item["pic"].split("/")[-2])
# 文件写
with open(filename, "wb") as file:
file.write(content)
def main():
#分页
for i in range(1,65):
print(i)
get_data(base_url.format(i))
if __name__ == '__main__':
main()