毕设总结2:使用python scrapy 爬取 网易云音乐

痛定思痛。 2021-09-28 23:16 1111阅读 0赞

网易云音乐爬取教程

      • 爬取网易云热歌榜
        • 分析网页结构

爬取网易云热歌榜

分析网页结构

先还是通过 [scrapy genspider music https://music.163.com/discover/toplist?id=3778678] 创建scrapy爬虫默认模板。参考毕设总结1
然后把目标url(api)放在这里:网易云热歌榜传送门

首先分析以下歌曲名:
歌曲名
这里我用css选择器去匹配这个b标签,

  1. response.css('.txt a b::attr(title)').extract()

获取有问题
但是这里出现了问题,显然他的数据是通过js动态加载的,所以需要找出api。
后来通过上网发现,其实歌曲数据都放在textarea中

  1. str_data = response.css("textarea::text").extract()[0]

歌曲信息
获取到歌曲信息后,需要把str转换成json,然后遍历获取想要的数据。
部分的代码:

  1. import scrapy
  2. from datetime import datetime
  3. import json
  4. import time
  5. from ArticleSpider.items import MusicItem
  6. class MusicSpider(scrapy.Spider):
  7. name = 'music'
  8. allowed_domains = ['music.163.com/discover/toplist?id=3778678']
  9. start_urls = ['https://music.163.com/discover/toplist?id=3778678']
  10. headers = {
  11. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
  12. }
  13. def parse(self, response):
  14. music_item = MusicItem()
  15. update_time = response.css(".user span::text").extract()[0] # 榜单发布时间
  16. update_time = update_time.replace("最近更新:", "")
  17. str_data = response.css("textarea::text").extract()[0]
  18. json_data = json.loads(str_data)
  19. for i in range(len(json_data)):
  20. if json_data[i].get('publishTime') != 0:
  21. t1 = time.localtime(json_data[i].get('publishTime')/1000)
  22. publish_time = time.strftime("%Y-%m-%d %H:%M:%S", t1) # 发行时间
  23. else:
  24. publish_time = "2019-01-01"
  25. song_time = json_data[i].get('duration')/1000 # 歌曲时长
  26. song_time_min = str(song_time/60)
  27. song_time_min = song_time_min.split(".")[0]
  28. song_time_sec = str(song_time - int(song_time/60)*60)
  29. song_time_sec = song_time_sec.split(".")[0]
  30. if len(song_time_sec)<2:
  31. song_time_sec = '0'+str(song_time_sec)
  32. # song_time_sec = song_time_sec[0:2]
  33. if len(song_time_min)<2:
  34. song_time_min = '0'+str(song_time_min)
  35. song_time = song_time_min+":"+song_time_sec
  36. # print(song_time)
  37. # 歌手
  38. artist = json_data[i].get('artists')[0].get('name')
  39. # 歌手id
  40. artist_id =json_data[i].get('artists')[0].get('id')
  41. # 歌名
  42. music_name = json_data[i].get('name')
  43. # 音乐id
  44. music_id = json_data[i].get('id')
  45. # 音乐下载地址
  46. music_down_url = "http://music.163.com/song/media/outer/url?id="+str(music_id)+".mp3"
  47. # 歌曲url
  48. music_url = "https://music.163.com/song?id="+str(music_id)
  49. # 专辑
  50. album = json_data[i].get('album').get('name')
  51. # 专辑图url
  52. pic_url = json_data[i].get('album').get('picUrl')
  53. # 专辑id
  54. album_id = json_data[i].get('album').get('id')
  55. # 排名
  56. no = json_data[i].get('no')
  57. # 上次排名
  58. if json_data[i].get('lastRank'):
  59. last_rank = json_data[i].get('lastRank')
  60. else:
  61. last_rank = "未上榜"
  62. crawl_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  63. music_item["publish_time"] = publish_time # 歌曲发布时间
  64. music_item["song_time"] = song_time # 歌曲时长
  65. music_item["artist"] = artist # 歌手
  66. music_item["artist_id"] = artist_id # 歌手id
  67. music_item["music_name"] = music_name # 歌名
  68. music_item["music_id"] = music_id # 歌曲id id
  69. music_item["album"] = album # 专辑
  70. music_item["pic_url"] = pic_url # 专辑封面图
  71. music_item["album_id"] = album_id # 专辑id
  72. music_item["no"] = no # 本周排名
  73. music_item["last_rank"] = last_rank # 上周排名
  74. music_item["crawl_time"] = crawl_time # 爬取时间
  75. music_item["music_down_url"] = music_down_url # 歌曲下载地址 外链
  76. music_item["music_url"] = music_url # 歌曲url
  77. music_item["update_time"] = update_time # 榜单发布时间
  78. yield music_item
  79. pass

发表评论

表情:
评论列表 (有 0 条评论,1111人围观)

还没有评论,来说两句吧...

相关阅读

    相关 音乐评论

    前言 我是个很喜欢听歌的人,手机里面下了几百首歌,而且还会每个月还会增加几首,因为我觉得听歌能让我活得更有趣。平常的我,喜欢听一些流行歌曲或者被翻唱突然又火起来的老歌、无