<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          今天你網(wǎng)易云了么

          共 8624字,需瀏覽 18分鐘

           ·

          2020-12-17 12:41

          很久之前曾經(jīng)寫過一篇聽什么歌都像是在唱自己的推送,寫的是網(wǎng)易云的歌,可以點一以下鏈接穿越。聽什么歌,都像在唱自己今天我們不是來談音樂情懷的,而是python爬蟲技術(shù)分享。接上一篇下廚房的爬蟲文章,這次給大家?guī)淼氖蔷W(wǎng)易云爬蟲。利用爬蟲爬取我喜歡的音樂前1000個并做成詞云圖。
          分解一下項目,首先需要找到對應(yīng)的鏈接,然后把歌曲名字,演唱者,專輯圖片下載下來。如下圖所示,可以看到,網(wǎng)易云我喜歡的音樂里面有1000多個,這里我們?nèi)∏?000個進(jìn)行分析。

          05518860ef13ec988e0d86e5aab88fa5.webp


          說干就干,request搞起來
          import requestsurl = 'https://music.163.com/#/my/m/music/playlist?id=127497555'res = requests.get(url=url)print(res.text)
          #返回的內(nèi)容里有手機(jī)號登錄
          一頓操作之后,你會發(fā)現(xiàn),雖然你get到了正確的響應(yīng)碼200,頁獲取了網(wǎng)頁的內(nèi)容,但是內(nèi)容確是重定向到music.163.com,看返回的內(nèi)容就知道是登錄界面。這時候猜想,因為沒有登錄所以返回讓你登錄的頁面。這時候就要想辦法模擬登錄。模擬登錄需要找到登錄網(wǎng)址。登錄的時候按F12查看Network選項下的記錄,刷新的網(wǎng)頁比較多,可以加個過濾,只看XHR(可以簡單理解為post請求)可以參考下圖。b對應(yīng)的網(wǎng)站是提交登錄按鈕的時候發(fā)送的請求,返回的只是一個狀態(tài),沒有內(nèi)容。下面一個cellphone像是手機(jī)登錄的實際入口,返回的都是和個人賬戶相關(guān)的內(nèi)容。

          46eb98f03c52dc6bf36be05b3a9d5fb8.webp

          研究這兩個請求,嘗試向這兩個網(wǎng)址提交賬號密碼 數(shù)據(jù)https://ac.dun.163yun.com/v3/b , https://music.163.com/weapi/user/grabed/status/get?csrf_token=4a2d3da0210ddb2618018149c4c4e824,使用post方法,帶上需要提交的賬戶密碼,結(jié)果得不到正確的響應(yīng)。在data里加上'remember':'True'后,還是得不到200響應(yīng)。

          data = {    'username':'',????'password':'',????'remember':''}res = requests.post(url=url,headers=headers,data=data)
          這時候百度搜了一下先驅(qū)們的做法和思路。原來網(wǎng)易云進(jìn)行了js加密。你提交的數(shù)據(jù)需要經(jīng)過算法加密了之后提交。而且同一個輸入,每一次加密的結(jié)果是不同的。

          c77d58a4714ed9477ec489f9e28022c0.webp

          所以需要研究加密算法。破解加密算法的過程參考https://www.zhihu.com/question/36081767 如何爬網(wǎng)易云音樂的評論數(shù)?
          # 生成16個隨機(jī)字符def generate_random_strs(length):    string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"    # 控制次數(shù)參數(shù)i    i = 0    # 初始化隨機(jī)字符串    random_strs  = ""    while i < length:        e = random.random() * len(string)        # 向下取整        e = math.floor(e)        random_strs = random_strs + list(string)[e]        i = i + 1    return random_strs
          # AES加密def AESencrypt(msg, key): # 如果不是16的倍數(shù)則進(jìn)行填充(paddiing) padding = 16 - len(msg) % 16 # 這里使用padding對應(yīng)的單字符進(jìn)行填充 msg = msg + padding * chr(padding) # 用來加密或者解密的初始向量(必須是16位)????iv?=?'0102030405060708' cipher = AES.new(bytearray(key,'utf-8'),AES.MODE_CBC, bytearray(iv,'utf-8')) # 加密后得到的是bytes類型的數(shù)據(jù) encryptedbytes = cipher.encrypt(bytearray(msg,'utf-8')) # 使用Base64進(jìn)行編碼,返回byte字符串 encodestrs = base64.b64encode(encryptedbytes) # 對byte字符串按utf-8進(jìn)行解碼????enctext?=?encodestrs.decode('utf-8') return enctext
          # RSA加密def RSAencrypt(randomstrs, key, f): # 隨機(jī)字符串逆序排列 string = randomstrs[::-1] # 將隨機(jī)字符串轉(zhuǎn)換成byte類型數(shù)據(jù) text = bytes(string, 'utf-8') seckey = int(codecs.encode(text, encoding='hex'), 16)**int(key, 16) % int(f, 16) return format(seckey, 'x').zfill(256)# 獲取參數(shù)def?get_params(text): msg = text key = '0CoJUm6Qyw8W8jud' f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7' e = '010001' enctext = AESencrypt(msg, key) # 生成長度為16的隨機(jī)字符串 i = generate_random_strs(16) # 兩次AES加密之后得到params的值 encText = AESencrypt(enctext, i) # RSA加密之后得到encSecKey的值 encSecKey = RSAencrypt(i, e, f) return encText, encSecKey
          這個加密過程是通過研究網(wǎng)易云刷新頁面的時候調(diào)用的js文件,然后搜索關(guān)鍵字encSecKey得到,這幾個abcde來回倒騰,捋清楚他們之間的關(guān)系,解密算法就可以寫出來了。

          9882c98085e6b513adf1f1dc4076864a.webp

          理解這個加密解密過程并不難,重點是需要自己動手實踐一遍。博主大神們想要爬取的網(wǎng)站跟我的并不相同,網(wǎng)上的參考資料也不全對,需要自己動手實踐。動手實踐步驟可參考參考鏈接?'糕糕python'的博文?https://www.jianshu.com/p/a45714d16294?網(wǎng)易云音樂爬蟲(JS破解全過程)

          知道了js解密之后,還需要知道對什么數(shù)據(jù)進(jìn)行加密,就是你加密的數(shù)據(jù)格式是怎樣的,這一步需要抓包工具。這里我們使用fiddler。梳理加密過程實踐
          • 安裝fiddler軟件,fiddler所有權(quán)使用說明以fiddler官網(wǎng)為準(zhǔn)

          • 安裝好之后熟悉界面操作,我們主要使用左邊的界面來關(guān)注所有的收發(fā)消息和右邊工具欄下的AutoResponder(fiddler需要安裝一下認(rèn)證證書,瀏覽器和網(wǎng)頁的通信會出問題)

          • 因為登錄提交數(shù)據(jù)的時候,是經(jīng)過js加密的,我們更改一下fiddler的默認(rèn)配置,使得訪問js的消息會黃色高亮

          996afe2887dbc0818f3204f22e81d614.webp

          • 在network里面Initiator里面可以查看對應(yīng)的js文件,在瀏覽器中可以將js保存到本地查看。我們需要關(guān)注的是core.js(網(wǎng)站上core后面會帶一串?dāng)?shù)字)

          • 有點代碼基礎(chǔ)的小伙伴可以把這個js的調(diào)用關(guān)系捋一下,捋完了就可以看懂博主們寫的代碼

          • js文件里面是加密過程的破解,這個加密是有一個輸入的,這個輸入是需要通過打印的方式得到的,這個是我們提交數(shù)據(jù)的格式。在本地的js文件里加上這兩句打印。

          64dab212f8efaf073353946654116f6c.webp

          • 在fiddler中,設(shè)置,當(dāng)訪問數(shù)據(jù)請求core.js的時候,就使用本地的js來做響應(yīng)。(相當(dāng)于截胡)這樣就可以順利的看到請求的數(shù)據(jù)格式,見下圖

          6991e6ff87eb14f8ba93166b04400d67.webp

          • 可以看到請求播放列表的時候提交的數(shù)據(jù)格式為'id': 'offset': "",'total': "",'limit': "",'n': "",'csrf_token': ""知道提交格式后,填進(jìn)去個人信息,然后就可以歡快的使用request.post了

          defcreate_form_data(self):      text = json.dumps(self.text)      params, encSecKey = get_params(text)      form_data = {'params': params, 'encSecKey': encSecKey}        return form_datadef get_song_list(self):      data = self.create_form_data()      res = requests.post(self.link, headers= self.header, data=data)      with open(r'data/wyy.json', 'wb') as f:          f.write(res.content)      if(res.status_code == 200):          print('歌曲列表網(wǎng)頁下載成功')      else:          print('歌曲列表網(wǎng)頁下載失敗,響應(yīng)碼為{}'.format(res.status_code))
          • 同樣的方式可以得到登錄界面的數(shù)據(jù)格式為'phone': '','password': '','rememberLogin': '','checkToken' : '','csrf_token' : '',其中password是hash之后的數(shù)據(jù)?

          • 爬取不同的界面,需要提交的數(shù)據(jù)格式不同,所以一定要學(xué)會使用fiddler截胡各個頁面


          接下來是完善request請求

          • 完善請求時候的請求頭,還有cookie信息,目前網(wǎng)易云對于csrf_token沒有啟用校驗如果開啟的話,還需要把cookie里面的信息放到請求頭里使用

          035c4c4d92f764da76013ac46bcb51ef.webp

          headers?=?{    "Accept": "*/*",    "Accept-Encoding": "gzip,deflate,br",    "Accept-Language": "zh-CN,zh;q=0.9",    "Connection": "keep-alive",    "Content-Type": "application/x-www-form-urlencoded",    "Host": "music.163.com",    "Referer": "https://music.163.com/my/",    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36",    'Cookie' : 'NMTID=00OtwnUrt3vyloXqU3CrJQUz0o-yFUAAAF2LNqIrA; JSESSIONID-WYYY=AXdnG8nFpoY6PNi3XDdHgu99GoiK59brvkdEsAWd9Dk4u1089gqezazwWxWhCNNZ9wU7CoCFKXJhAboxaOMPRaVS2kmxgYb03I8th7aD72uXAHpQI6CUZRO6IldW%2FRgqPz1EAj2ozCzEeT957j826t78SS%2FOsKrilkCIue0PlHdK0t%2F%2B%3A1607082653296; _iuqxldmzr_=32; _ntes_nnid=9b95e833cabaf03992755f38d129f286,1607070412949; _ntes_nuid=9b95e833cabaf03992755f38d129f286; WM_NI=awDKKogly2FEWYgqHXRmTkHJIAqvPztlqKzum6mrAwE4kFsMecGBGSLRKKcT4nr5dA3tA6aOcqLjivp4L%2F65CRg1H4ijf6oJ7a67Bw43FuWIGjyz3qzGENdashEyPenNN2o%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eea8c445edb388d1b770a68e8eb3c54f838f8eabaa6f96a6a5daf85fb391bd92c52af0fea7c3b92aa3a98cacca65a5b4b7d3c54f9587a992cb5492b39c8ccb428b9fbf97d372b8b4bfacf97fafeaa393c47d87eca5a7f247a7bd89a3c659908e85ace260f8b2bed6e74bf1ac8fd7e445a1af848bec7eb4ec84d0b53f818ea9d2cb40abb6aad7ee42f5bffad8c17df8ed8a96d64385b6b79bb27bba998bafe76bb1b88b9ad36fae9282d3ee37e2a3; WM_TID=YeT5mqogqlRAVABRAUdueB3h9rV%2BO86Q; ntes_kaola_ad=1; WEVNSM=1.0.0; WNMCID=xqvafx.1607073379709.01.0; __remember_me=true; MUSIC_U=56131b60258d038b13494f63fb6163f1bf9b6ae5b82252dab58e6be3caa4bce20931c3a9fbfe3df2; __csrf=0251ce2d0e4fad451746504430572ee3'}
          • 請求頭設(shè)置好之后,如果你的數(shù)據(jù)格式,加密算法都沒有問題的話,使用post方法應(yīng)該就可以收到200響應(yīng),同時帶有你想要的數(shù)據(jù)

          • 補(bǔ)充一下,get和post方法的區(qū)別,get就像是一個靜態(tài)頁面,東西已經(jīng)加載好了在那里,你一調(diào)用get,就給你返回數(shù)據(jù)

          • post方法更像是動態(tài)頁面,東西沒準(zhǔn)備好,你post的時候告訴服務(wù)器你需要什么東西,然后服務(wù)器驗證一下你提交的格式對不對,對的話,再匆匆忙忙把你要的寶貝返回給你


          處理返回的數(shù)據(jù)

          • 歌名,演唱者信息可以在返回的數(shù)據(jù)里直接拿到

          • 專輯圖片的鏈接也在返回數(shù)據(jù)里,啟用一個多進(jìn)程將這些圖片下載下來。進(jìn)程數(shù)按照cpu的核數(shù)來設(shè)置。如果你不幸有一個12核的cpu的話,那你下載速度會非常快

          def muti_process(self):    # urls = urls[0:21]    #拿前20個做實驗    pool = Pool(cpu_count())    with open(r'data/pic_link.txt', 'rb') as f:        urls = f.read()    urls = urls.decode('utf-8').split()    print('多線程啟動')    pool.map(self.downlaod_album, urls)    pool.close()????pool.join()????def?downlaod_album(self,url):    try:        with open(r'output/album/{}.png'.format(url[-15:-4]), 'wb') as f:            f.write(requests.get(url).content)            print('圖片下載成功')        # print(url[-10:-4])    except ConnectionError:        print('Error Occured ', url)    finally:        print('下載任務(wù)執(zhí)行完畢')
          • 調(diào)用wordcloud模塊生成詞云圖

            def draw_wordcloud(self,file,pic):      self.pic = pic      mytext = self.cut_word(file)      mask = imread(self.pic, pilmode="RGB")      wc = WordCloud(          # 設(shè)置字體,不指定就會出現(xiàn)亂碼          font_path=r"C:\Windows\Fonts\simhei.ttf",          #避免詞的重復(fù)          collocations = False,          # 設(shè)置背景色          background_color='white',          # 設(shè)置背景寬          width=500,          # 設(shè)置背景高          height=350,          # 最大字體          max_font_size=50,          # 最小字體          min_font_size=10,          font_step=4,          mode='RGBA',          # colormap='pink'          mask=mask      )      # 產(chǎn)生詞云      wc.generate(mytext)      wc.to_file(r"output/wordcloud.png")  # 按照設(shè)置的像素寬高度保存繪制好的詞云圖,比下面程序顯示更清晰      print('詞云圖片保存成功')
          • 調(diào)用cv2/pil模塊處理專輯圖片 ->這部分內(nèi)容詳見另一個github,https://github.com/ZhouFall/image_handle

          最后的結(jié)果如下:可以看出,喜歡的歌手是陳奕迅和高梨康治(火影的作曲),說明一下,詞云圖只能反映出現(xiàn)的次數(shù)多少,可以用來看個趨勢。喜歡的歌,cover和翻自出現(xiàn)的比較多,大概是因為喜歡聽翻唱的吧(也有因為貧窮,聽不到正版的原因)

          95a168be75ab3dc7aec0814e4302645e.webp

          69216d045784559387c9941d06cc1685.webp

          8d6296cb1df9e2000752bbb240da9cf1.webp

          ce569b539d9bb9b85b7daa03264cfb68.webp

          整個網(wǎng)易云爬蟲的詳細(xì)代碼可以在git鏈接里找到https://github.com/ZhouFall/music_spider 如果readme界面圖片不顯示,可以在C:\windows\System32\drivers\etc目錄下的hosts.ics文件里添加199.232.68.133 raw.githubusercontent.com # comments. put the address here?


          參考網(wǎng)站:
          1. https://www.jianshu.com/p/a45714d16294?網(wǎng)易云音樂爬蟲(JS破解全過程)

          2. https://www.cnblogs.com/bcaixl/p/13928629.html?python3爬蟲應(yīng)用--爬取網(wǎng)易云音樂(兩種辦法)

          3. https://blog.csdn.net/weixin_42555080/article/details/90105330?Python爬蟲之網(wǎng)易云音樂數(shù)據(jù)爬取(十五)

          4. https://www.zhihu.com/question/36081767 如何爬網(wǎng)易云音樂的評論數(shù)?

          5. https://www.zhihu.com/question/36081767/answer/65820705 如何爬網(wǎng)易云音樂的評論數(shù)?

          6. https://blog.csdn.net/qq_39138295/article/details/89226990?request保持會話,尋找set-cookie來獲取數(shù)據(jù)


          瀏覽 89
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲欧美毛片高清 | 国产在线无码观看 | 久久久久久久久久成人永久免费视频 | 最近中文字幕免费mv第一季歌词完整版 | 日本东京热视频 |