Scrapy爬取網(wǎng)易云音樂和評論(五、評論)

目錄:

1、Scrapy爬取網(wǎng)易云音樂和評論(一、思路分析)
2、Scrapy爬取網(wǎng)易云音樂和評論(二、Scrapy框架每個模塊的作用)
3、Scrapy爬取網(wǎng)易云音樂和評論(三、爬取歌手)
4、Scrapy爬取網(wǎng)易云音樂和評論(四、關(guān)于API)
5、Scrapy爬取網(wǎng)易云音樂和評論(五、評論)

評論的API的參考鏈接:

1、https://github.com/darknessomi/musicbox/wiki/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90%E6%96%B0%E7%89%88WebAPI%E5%88%86%E6%9E%90%E3%80%82(這個是從歌單下手的,里面的評論可以參考)
2、http://www.imooc.com/article/17459?block_id=tuijian_wz
3、http://blog.csdn.net/u012104691/article/details/53766045
后面這幾篇都講的比較詳細(xì),當(dāng)時查資料的時候,還查到另外一種寫法,就是里面有一堆命名是first_param什么的,看得頭暈眼花,然后當(dāng)時測試似乎也沒有成功,建議用現(xiàn)在的這種就好了。

基本模式就是這樣:


來自https://github.com/darknessomi/musicbox/wiki/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90%E6%96%B0%E7%89%88WebAPI%E5%88%86%E6%9E%90%E3%80%82

因為專輯和歌曲都有評論,所以我專門將它寫成了個類,后面直接調(diào)用就可以了。

# -*-coding:utf-8-*-
import os
import re
import sys
import json
import base64
import binascii
import hashlib
import requests
from Crypto.Cipher import AES

class CommentCrawl(object):
    '''評論的API封裝成一個類,直接傳入評論的API,再調(diào)用函數(shù)get_song_comment()和get_album_comment()即可分別獲取歌曲和專輯的評論信息
    '''

    def __init__(self,comment_url):
        self.comment_url = comment_url
        self.headers = {
            "Referer":"http://music.163.com",
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3067.6 Safari/537.36",
        }

    def createSecretKey(self,size):
        '''生成長度為16的隨機字符串作為密鑰secKey
        '''
        return (''.join(map(lambda xx: (hex(ord(xx))[2:]), os.urandom(size))))[0:16]

    def AES_encrypt(self,text, secKey):
        '''進行AES加密
        '''
        pad = 16 - len(text) % 16
        text = text + pad * chr(pad)
        encryptor = AES.new(secKey, 2, '0102030405060708')
        encrypt_text = encryptor.encrypt(text.encode())
        encrypt_text = base64.b64encode(encrypt_text)
        return encrypt_text

    def rsaEncrypt(self, text, pubKey, modulus):
        '''進行RSA加密
        '''
        text = text[::-1]
        rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
        return format(rs, 'x').zfill(256)

    def encrypted_request(self, text):
        '''將明文text進行兩次AES加密獲得密文encText,
        因為secKey是在客戶端上生成的,所以還需要對其進行RSA加密再傳給服務(wù)端。
        '''
        pubKey = '010001'
        modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
        nonce = '0CoJUm6Qyw8W8jud'

        text = json.dumps(text)
        secKey = self.createSecretKey(16)
        encText = self.AES_encrypt(self.AES_encrypt(text, nonce), secKey)
        encSecKey = self.rsaEncrypt(secKey, pubKey, modulus)
        data = {
            'params': encText,
            'encSecKey': encSecKey
        }
        return data   

    def get_post_req(self, url, data):
        try:
            req = requests.post(url, headers=self.headers, data=data)
        except Exception,e:
            # dosomething
            print url,e
            # return None
        return req.json()            

    def get_offset(self, offset=0):
        '''偏移量
        '''
        if offset == 0:
            text = {'rid':'', 'offset':'0', 'total':'true', 'limit':'20', 'csrf_token':''} 
        else:
            text = {'rid':'', 'offset':'%s' % offset, 'total':'false', 'limit':'20', 'csrf_token':''} 
        return text

    def get_json_data(self,url,offset):
        '''json 格式的評論
        '''
        text = self.get_offset(offset)
        data = self.encrypted_request(text)
        json_text = self.get_post_req(url, data)
        return json_text

    def get_song_comment(self):
        '''某首歌下全部評論
        '''
        comment_info = []
        data = self.get_json_data(self.comment_url,offset=0)
        comment_count = data['total']
        if comment_count:
            comment_info.append(data)
            if comment_count > 20:
                for offset in range(20,int(comment_count),20):
                    comment = self.get_json_data(self.comment_url,offset=offset)
                    comment_info.append(comment)
        return comment_info

    def get_album_comment(self,comment_count):
        '''某專輯下全部評論
        '''
        album_comment_info = []
        if comment_count:
            for offset in range(0,int(comment_count),20):
                comment = self.get_json_data(self.comment_url,offset=offset)
                album_comment_info.append(comment)
        return album_comment_info

重復(fù)的地方我就不贅述了,最后兩個地方我之所以分開寫,是因為專輯的評論數(shù)可以從專輯信息里獲取,但歌曲評論數(shù)從專輯列表信息里獲取不到,只能先爬取它第一頁的json數(shù)據(jù),它里面的total就是評論總數(shù),然后再做后面的處理。

評論的API:

# 1、專輯評論API:
comment_url = 'http://music.163.com/weapi/v1/resource/comments/R_AL_3_%s?csrf_token=' % album_id
# 2、歌曲評論API:
comment_url = 'http://music.163.com/weapi/v1/resource/comments/R_SO_4_%s?csrf_token=' % song_id

然后將comment_url 作為參數(shù)傳入上面封裝的那個類里即可,不同的是專輯還需先獲取專輯評論的數(shù)量。

所有的分析都結(jié)束了,接下來的代碼自己寫吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄: 1、Scrapy爬取網(wǎng)易云音樂和評論(一、思路分析)2、Scrapy爬取網(wǎng)易云音樂和評論(二、Scrapy...
    蘇酒酒閱讀 1,432評論 0 0
  • 嘿,你說自己脾氣差情商低說起來還理直氣壯的是怎么回事,那我的不知所措,難過崩潰,自我反思,新生蛻變,再放下自尊一次...
    SweetCC閱讀 150評論 0 0
  • 在oc中如果沒有使用ARC的話,手動管理內(nèi)存一定要注意處理好“野指針”,通常我們在釋放指針的指向的地址時,...
    Mr_Arvin閱讀 504評論 0 0
  • 《明天的你一定感謝今天的自己:時間掌控術(shù)》這本書分享了在這個飛轉(zhuǎn)的社會如何把掌控好時間,帶來高效的成功。 1、注重...
    遇上緣閱讀 692評論 0 0

友情鏈接更多精彩內(nèi)容