爬虫练习:爬取网易云音乐热歌榜全部歌曲的热门评论

目标:爬取网易云音乐热歌榜中全部歌曲(共200首)的热门评论(每首歌有15个热门评论)

分析:

需要分两步走,第一步是定位到热歌榜单所在的资源,从而得到这热歌榜中到底有哪些歌并获得每首歌的id;第二步是根据上一步得到的每首歌的id,定位到单独每首歌所在的资源,从而得到每首歌下的评论信息。具体讲:

1)首先我们需要得到热歌榜数据所在的url,经浏览器开发者工具查看网页代码,得知热歌榜的数据所在的请求url是:

http://music.163.com/discover/toplist?id=3778678

这个url的请求方式是get方式,返回的是html的doc文档,这个文档中的第610行就包含了每首歌的歌名,id,以及对应的播放资源链接。

所以我们的第一个任务就是把该html文档爬取下来,提取出所有歌曲的名称及id。有了歌曲id之后,我们可以进一步通过这个id访问到每一首歌的具体信息。

2)在网页上点进某一首歌的链接,分析弹出的每首歌单独的新页面的Network情况,我们可以分析出包含该首歌歌评的请求url为:

http://music.163.com/weapi/v1/resource/comments/R_SO_4_489998494?csrf_token=,

请求方式是post(因为评论需要往服务端发送数据),返回的是json文件,在该json文件中就包含了我们需要的热门评论。在这里唯一有点棘手的地方是发送post请求时需要两个参数,而不同的歌这两个参数是不同的(然而程序中用的参数是相同的),关于这两个参数如何定,具体介绍在下面的链接中。

所以下一步任务就是通过post请求把该json文件爬取下来,并提取出其中的热门评论信息。

下面代码的详细介绍请参见:https://blog.csdn.net/fengxinlinux/article/details/77950209法

#获取网易云热歌榜所有歌曲的名称和id
def get_all_hotSong():
    url = "http://music.163.com/discover/toplist?id=3778678"                   #网易云音乐热歌榜url
    
    ua_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) \
                                AppleWebKit/537.36 (KHTML, like Gecko) \
                                Chrome/60.0.3112.101 \
                                Safari/537.36'}                                #请求头部           
                            
    request = urllib.request.Request(url=url, headers=ua_headers)              #构造请求对象
    
    html = urllib.request.urlopen(request).read().decode('utf8')               #打开url
    
    html = str(html)                                                           #转换为str
    
    #我们要筛选的html字段例如:
    
    part1 = r''#进行第一次筛选的正则表达式,注意在这里有问号(本身是正则表达式的元字符)前要使用转义符\
                                                                               
    result = re.compile(part1).findall(html)                                   #用正则表达式进行筛选,返回的结果存在列表中
    
    result = result[0]                                                         #获取list的第一个元素
    
    part2 = r'
  • (.*?)
  • ' #进行歌名筛选的正则表达式 part3 = r'
  • .*?
  • ' #进行歌id筛选的正则表达式 hot_song_name = re.compile(part2).findall(result) #获取所有热门歌曲名称 hot_song_id = re.compile(part3).findall(result) #获取所有热门歌曲id return hot_song_name, hot_song_id #返回的是两个list #参数是歌曲名和id(由上一个函数返回),返回的是每首歌下的15条热评 def get_hotComments(hot_song_name, hot_song_id): #每首歌使用单独的url请求 url = 'https://music.163.com/weapi/v1/resource/comments/R_SO_4_' + hot_song_id + '?csrf_token=' ua_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) \ AppleWebKit/537.36 (KHTML, like Gecko) \ Chrome/60.0.3112.101 \ Safari/537.36'} #请求头部 #post请求表单数据,以字典形式组织参数 data = {'params':'Ms46IEnUeE4P/yfU6xsyEtEcjeRfhckhg/sBdqIG2tLBXGPoZ7MGVOZsu2AdyLQ+ZTPDvjf1OjalqcSSJLfBmf1vvbVx8cvv8MVoHYOQ6wCRnd2/6+GMfu1M13fbNXVb9aKiduqxPZjZrMsTgX5jecxsXs/rzP9KLRWDDMkvxusGini/WGaWDKGrBQj4cm4k', \ 'encSecKey':'b049e6104264186dfaceba5f9a60dc39e8cf6900dac42a58223074346b758a4ca0fc66006a39a8d54e43cc95c271b415b69efa8a81742f06230a105e32a6f11128e8d526450a81f3245ce0fb5f5974de18207e6e3cdaf87b63572fcb7ad720124b19049457fe19c8f7f3424c3eae45d530b743ee7dec5ef78d15c2dbbc258975'} postdata = urllib.parse.urlencode(data).encode('utf8') #将参数进行编码 request = urllib.request.Request(url, headers=ua_headers, data=postdata) #构造请求对象 response = urllib.request.urlopen(request).read().decode('utf8') #打开url,返回类文件对象并读其内容 json_dict = json.loads(response) #获取json hot_comments = json_dict['hotComments'] #获取json中的热门评论 num = 0 fhandle = open('./song_comments.txt','a', encoding='utf-8') #按appendix的方式打开文件 fhandle.write(hot_song_name+':'+'\n') for item in hot_comments: #按循环依次写入歌的每条评论 num += 1 fhandle.write(str(num)+'.'+item['content']+'\n') fhandle.write('\n==============================\n\n') fhandle.close() #==============================主程序入口======================================= #返回网易云热歌榜所有歌曲的名称和id hot_song_name, hot_song_id = get_all_hotSong() num = 0 while num < len(hot_song_name): print('正在抓取第%d首歌曲热评...'%(num+1)) get_hotComments(hot_song_name[num], hot_song_id[num]) print('第%d首歌曲热评抓取成功'%(num+1)) num += 1

    你可能感兴趣的:(爬虫练习:爬取网易云音乐热歌榜全部歌曲的热门评论)