A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

项目GitHub地址:https://github.com/sujiujiu/WYYScrapy

评论的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
后面这几篇都讲的比较详细,当时查资料的时候,还查到另外一种写法,就是里面有一堆命名是first_param什么的,看得头晕眼花,然后当时测试似乎也没有成功,建议用现在的这种就好了。

基本模式就是这样:

图片代码来自:来自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

因为专辑和歌曲都有评论,所以我专门将它写成了个类,后面直接调用就可以了。

# -*-coding:utf-8-*-import osimport reimport sysimport jsonimport base64import binasciiimport hashlibimport requestsfrom Crypto.Cipher import AESclass CommentCrawl(object):    '''评论的API封装成一个类,直接传入评论的API,再调用函数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加密再传给服务端。        '''        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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111

重复的地方我就不赘述了,最后两个地方我之所以分开写,是因为专辑的评论数可以从专辑信息里获取,但歌曲评论数从专辑列表信息里获取不到,只能先爬取它第一页的json数据,它里面的total就是评论总数,然后再做后面的处理。

评论的API:

# 1、专辑:comment_url = 'http://music.163.com/weapi/v1/resource/comments/R_AL_3_%s?csrf_token=' % album_id# 2、歌曲:comment_url = 'http://music.163.com/weapi/v1/resource/comments/R_SO_4_%s?csrf_token=' % song_id
  • 1
  • 2
  • 3
  • 4

然后将comment_url 作为参数传入上面封装的那个类里即可,不同的是专辑还需先获取专辑评论的数量。
所有的分析都结束了,接下来的代码自己写吧。


2 个回复

倒序浏览
回复 使用道具 举报
奈斯,加油加油
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马