selenium爬取qq音乐

今日学习(解析selenium爬取qq音乐,附带解析数据)

点此查看原博客
爬取QQ音乐官网指定歌手的前5首歌曲的基本信息和前五百条热门评论:
selenium中文网点此学习selenium
简而言之,selenium就是运行在浏览器上面,相当于用户本身在操作的一个测试框架,用selenium爬取网页信息,实用性更强

driver=webdriver.Chrome(executable_path="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")
  • 浏览器对象打开网页:
driver.get("https://y.qq.com/n/yqq/singer/0025NhlN2yWrP4.html")
  • 获取所有歌曲,使用class name
    在这里插入图片描述
songlist__item=driver.find_elements_by_class_name("songlist__item")
  • 遍历所有歌曲,获取每一首歌曲的url (使用class name)存入之前创建的空列表当中,此操作为之后点击进入每一首歌曲的主界面,再进行获取的一些相关信息
for song in songlist__item:
    song__url=song.find_element_by_class_name("js_song").get_attribute("href")
    song_url_list.append(song__url)
    song_numer-=1
    if(song_numer==0):
        break
  • 创建函数,作用为获取一首歌的全部信息,以及相关歌词,前500条评论
def getSongResourse(url):
    song_resourse={}
    driver.get(url)
    # 这个0.5秒用于等待异步请求的完成
    sleep(0.8)

    # 获取歌曲名
    song_name=driver.find_element_by_class_name("data__name_txt").text

    print("开始获取歌曲《"+song_name+"》的基本信息")

    # 获取流派,发行时间,评论数
    song_liupai = driver.find_element_by_css_selector(".js_genre").text[3:]
    song_time = driver.find_element_by_css_selector(".js_public_time").text[5:]
    song_comment_num = driver.find_element_by_css_selector(".js_into_comment").text[3:-1]

    print("歌曲《" + song_name + "》基本信息获取完毕")

    print("开始获取歌曲《" + song_name + "》的歌词")

    # 点击展开歌词
    driver.find_element_by_partial_link_text("[展开]").click()        #此为模糊匹配元素文本【展开】
    sleep(0.3)
    lyic=""
    # 获取拼接歌词
    lyic_box=driver.find_element_by_id("lrc_content").find_elements_by_tag_name("p")
    for l in lyic_box:
        if l.text!="":
            lyic+=l.text+"\n"

    print("歌曲《" + song_name + "》的歌词获取完毕")

    print("开始获取歌曲《" + song_name + "》的第1-15条热门评论")

    # 获取500条评论
    comments=[]
    # 点击加载更多29次,每次多出15条评论
    for i in range(33):
        driver.find_element_by_partial_link_text("点击加载更多").click()
        print("开始获取歌曲《" + song_name + "》的第"+str((i+1)*15+1)+"-"+str((i+2)*15)+"条热门评论")
        sleep(0.5)
    comments_list=driver.find_element_by_css_selector(".js_hot_list").find_elements_by_tag_name("li")
    for com in comments_list:
        content=com.find_element_by_css_selector(".js_hot_text").text
        content_time=com.find_element_by_css_selector(".comment__date").text
        zan_num=com.find_element_by_class_name("js_praise_num").text

        comment = {}
        comment.update({"评论内容":content})
        comment.update({"评论时间":content_time})
        comment.update({"评论点赞次数":zan_num})
        comments.append(comment)

    print("歌曲《" + song_name + "》的前五百条热门评论获取完毕")

    print("歌曲《"+song_name+"》所有信息获取完毕")
    print()
    song_resourse.update({"歌曲名":song_name})
    song_resourse.update({"流派":song_liupai})
    song_resourse.update({"发行时间":song_time})
    song_resourse.update({"评论数":song_comment_num})
    song_resourse.update({"歌词":lyic})
    song_resourse.update({"500条精彩评论":comments})
    return song_resourse

以上长代码块中使用css选择器的情况如下(此js_genre中间没有其他符号)原代码表示:

这里是定位元素之后的数据切片操作,源码为:

    song_liupai = driver.find_element_by_css_selector(".js_genre").text[3:]     
    song_time = driver.find_element_by_css_selector(".js_public_time").text[5:]
    song_comment_num = driver.find_element_by_css_selector(".js_into_comment").text[3:-1]

经过测试,此切片操作text[3:] 目的是去切除掉 流派: 这三个字符,留下的就是流派内容
text[5:]是切除 发行时间: 这五个字符,,text[3:-1] 是切除掉 评论()。切除掉前面3个字符和最后一个反括号

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
代码块如下:

# 获取流派,发行时间,评论数
    song_liupai = driver.find_element_by_css_selector(".js_genre").text[3:]     #css选择器
    song_time = driver.find_element_by_css_selector(".js_public_time").text[5:]
    song_comment_num = driver.find_element_by_css_selector(".js_into_comment").text[3:-1]
  • 获取一首歌详细信息函数(相关解析写在代码注释里面):
def getSongResourse(url):
    song_resourse={}
    driver.get(url)
    # 这个0.5秒用于等待异步请求的完成
    sleep(0.8)

    # 获取歌曲名
    song_name=driver.find_element_by_class_name("data__name_txt").text      #唯一的classname,可以使用此方法定位元素

    print("开始获取歌曲《"+song_name+"》的基本信息")

    # 获取流派,发行时间,评论数
    song_liupai = driver.find_element_by_css_selector(".js_genre").text[3:]    #第三个元素到最后
    song_time = driver.find_element_by_css_selector(".js_public_time").text[5:]  #第五个元素到最后
    song_comment_num = driver.find_element_by_css_selector(".js_into_comment").text[3:-1]   #从第三个元素到最后一个元素(不包括最后一个元素)

    print("歌曲《" + song_name + "》基本信息获取完毕")

    print("开始获取歌曲《" + song_name + "》的歌词")

    # 点击展开歌词
    driver.find_element_by_partial_link_text("[展开]").click()        #此为模糊匹配元素文本【展开】
    sleep(0.3)
    lyic=""
    # 获取拼接歌词
    lyic_box=driver.find_element_by_id("lrc_content").find_elements_by_tag_name("p")
    for l in lyic_box:
        if l.text!="":
            lyic+=l.text+"\n"

    print("歌曲《" + song_name + "》的歌词获取完毕")

    print("开始获取歌曲《" + song_name + "》的第1-15条热门评论")

    # 获取500条评论
    comments=[]
    # 点击加载更多29次,每次多出15条评论
    for i in range(33):
        driver.find_element_by_partial_link_text("点击加载更多").click()
        print("开始获取歌曲《" + song_name + "》的第"+str((i+1)*15+1)+"-"+str((i+2)*15)+"条热门评论")
        sleep(0.5)                            #先模拟点击29次加载更多,全部加载出来再读取歌词
    comments_list=driver.find_element_by_css_selector(".js_hot_list").find_elements_by_tag_name("li")
    for com in comments_list:
        content=com.find_element_by_css_selector(".js_hot_text").text                  #css选择器
        content_time=com.find_element_by_css_selector(".comment__date").text        #定位评论时间
        zan_num=com.find_element_by_class_name("js_praise_num").text                #点赞数目

        comment = {}
        comment.update({"评论内容":content})                 #在列表中添加字典
        comment.update({"评论时间":content_time})
        comment.update({"评论点赞次数":zan_num})
        comments.append(comment)                            #此列表中嵌入字典(其中每条评论都是一个字典)

    print("歌曲《" + song_name + "》的前五百条热门评论获取完毕")

    print("歌曲《"+song_name+"》所有信息获取完毕")
    print()
    song_resourse.update({"歌曲名":song_name})
    song_resourse.update({"流派":song_liupai})
    song_resourse.update({"发行时间":song_time})
    song_resourse.update({"评论数":song_comment_num})
    song_resourse.update({"歌词":lyic})
    song_resourse.update({"500条精彩评论":comments})           #此处加入列表
    return song_resourse             #返回每一首歌的以上信息,循环5次

for song_page in song_url_list:      #
    song_resourses.append(getSongResourse(song_page))         #5手歌曲合并为1个列表
    # break
  • 写入csv文件
for song_page in song_url_list:
    song_resourses.append(getSongResourse(song_page))
    # break
print("正在写入CSV文件...")
for i in song_resourses:
    writer.writerow([i["歌曲名"],i["流派"],i["发行时间"],i["评论数"],i["歌词"]])    #创建列
    for j in i["500条精彩评论"]:
        writer.writerow([j["评论内容"],j["评论时间"],j["评论点赞次数"]])
    writer.writerow([])
csv_file.close()
end = time.time()
print("爬取完成,总耗时"+str(end-start)+"秒")

. 爬虫重难点在于定位元素以及数据处理,这个项目是在列表中插入字典,再从此列表中遍历字典的键与值。再依次保存到csv文件中,也为今后爬取数据保存数据提供一个新思路。

csv文件打开乱码解决办法:

使用其它方式,选择记事本打开,另存为为一个文件(覆盖也行),存储格式选择为ANSI

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值