python爬虫音乐犯法么_我用一天时间“偷了”网易云音乐50W+用户信息 / python爬虫...

没有多进程,没有任何黑科技的裸爬虫。练手用,爬虫获取到的数据皆为公开且非敏感的用户信息。

目录

一、思路

二、参数加密流程分析

三、代码实现

common.py (需要用到的函数)

demo.py (主程序)

四、数据

一、思路

在GitHub上已经有网易云音乐的node.js API(GitHub:https://github.com/Binaryify/NeteaseCloudMusicApi)。根据这个库提供的信息,可以很轻易的获取到网易云音乐获取某个用户的粉丝信息接口的参数(接口限制只能获取100个),进而继续获取这100个粉丝的粉丝…简单的几层循环嵌套就能很轻易的拿到十万级到百万级的用户数据(非敏感用户信息)。

二、参数加密流程分析

__getFormData(data, __get_random_str())

参数1:data是dict数据,包含了表单的各个字段和数据

参数2:16位的随机字符串

最终return的是一个dict,包含了params和encSecKey两个参数

params

__get_encText(args1, random16str)

参数1:args1是__getFormData函数的参数1,是dict数据,包含了表单的各个字段和数据

参数2:random16str是__getFormData函数的参数2,是一个16位的随机字符串

最终返回的是将参数加密后产生的params

__AES_encrypt(args1, args4)

参数1:args1是__get_encText函数的参数1,是dict数据,包含了表单的各个字段和数据

参数2:arg4是一个固定参数

最终返回的是将参数使用AES CBC加密后再进行一次base64加密产生的字符串

使用__AES_encrypt函数首先加密一次参数是(args1,args4)得到一个加密的字符串

在使用加密过一次的字符串作为参数1,和__get_encText函数传入的参数2 random16str 这个随机16位的字符串作为参数2继续加密1次

最终得到params

encSecKey

__get_encSecKey(random16str)

参数1:random16str是__getFormData函数的参数2,是一个16位的随机字符串

最终返回的是通过随机字符串产生的encSecKey

固定参数arg2

固定参数arg3

通过固定算法,使用随机16位的字符串random16str与这两个固定参数产生encSecKey

三、代码实现

common.py (需要用到的函数)

import base64

from Crypto.Cipher import AES

import random

import codecs

import requests

from fake_useragent import UserAgent

def __AES_encrypt(text, key):

'''

获取到加密后的数据

:param text: 首先CBC加密方法,text必须位16位数据

:param key: 加密的key

:return: 加密后的字符串

'''

iv = "0102030405060708"

pad = 16 - len(text) % 16

if isinstance(text, str):

text = text + pad * chr(pad)

else:

text = text.deocde("utf-8") + pad * chr(pad)

aes = AES.new(key=bytes(key, encoding="utf-8"), mode=2, IV=bytes(iv, encoding="utf-8"))

res = aes.encrypt(bytes(text, encoding="utf-8"))

res = base64.b64encode(res).decode("utf-8")

return res

def __get_encText(args1, random16str):

args4 = "0CoJUm6Qyw8W8jud"

encText = __AES_encrypt(args1, args4)

encText = __AES_encrypt(encText, random16str)

return encText

def __get_encSecKey(random16str):

'''通过查看js代码,获取encSecKey'''

arg2 = "010001"

arg3 = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"

text = random16str[::-1]

rs = int(codecs.encode(text.encode('utf-8'), 'hex_codec'), 16) ** int(arg2, 16) % int(arg3, 16)

return format(rs, 'x').zfill(256)

def __get_random_str():

'''这是16位的随机字符串'''

str_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

random_str = ""

for i in range(16):

index = random.randint(0, len(str_set) - 1)

random_str += str_set[index]

return random_str

def __getFormData(args1, random16str):

'''获取到提交的数据'''

data = {"params": __get_encText(args1, random16str), "encSecKey": __get_encSecKey(random16str)}

return data

def __getFans(userID):

userDict = {}

userID = str(userID) # userID="6177307"

data = '{"userId":"' + userID + '","time":"-1","limit":"104334","csrf_token": ""}'

formdata = __getFormData(data, __get_random_str())

ua = UserAgent()

session = requests.Session()

headers = {}

headers["content-type"] = "application/x-www-form-urlencoded"

headers["user-agent"] = ua.random

headers["referer"] = "https://music.163.com/"

response = session.post(url='https://music.163.com/weapi/user/getfolloweds', headers=headers,

data=formdata)

results = response.json()

# print(response.status_code)

results = results.get('followeds')

for one in results:

userDict[one.get('userId')] = one

# print(one.get('userId'))

# print(str(one))

return userDict

demo.py (主程序)

# -*- coding: utf-8 -*-

import common

AllData = {}

data = common.__getFans(6177307)

AllData.update(data)

sum = 0

for item in data:

temp = common.__getFans(item)

AllData.update(temp)

for item1 in temp:

temp2 = common.__getFans(item1)

AllData.update(temp2)

for item2 in temp2:

sum += 1

print(sum)

temp3 = common.__getFans(item2)

AllData.update(temp3)

with open('fans.txt', 'a', encoding='utf-8') as f:

for one in AllData.items():

f.write(str(one) + '\n')

print(str(one))

四、数据

我把demo.py放到了服务器上运行,跑到程序结束大概用了24小时左右后看了一下存储的文本有50W左右的用户数据(不含敏感信息),以下用户信息为网易云公开数据,并且已经对部分数据进行打码。(已通过网易云音乐客户端私信征求用户同意)

(8****823, {'py': 'm**st', 'time': 1510*****4852, 'userId': 8******3, 'mutual': False, 'followed': False, 'accountStatus': 0, 'nickname': '名劍****收天', 'avatarUrl': 'http://p1.music.126.net/uocXBF145t-_V0pLWDwv0w==/3272146604393759.jpg', 'gender': 1, 'expertTags': None, 'experts': None, 'followeds': 13, 'remarkName': None, 'follows': 19, 'authStatus': 0, 'userType': 0, 'vipType': 0, 'signature': '天下若倾,尚有儒门一手擎天!', 'vipRights': None, 'eventCount': 1, 'playlistCount': 5})

(30****375, {'py': 'tt******y', 'time': 15107******003, 'userId': 305******5, 'mutual': False, 'followed': False, 'accountStatus': 0, 'nickname': '甜****ny', 'avatarUrl': 'http://p1.music.126.net/v9iyq-6I1WC96R7SlbKvXQ==/3420580709664324.jpg', 'gender': 1, 'expertTags': None, 'experts': None, 'followeds': 4, 'remarkName': None, 'follows': 30, 'authStatus': 0, 'userType': 0, 'vipType': 11, 'signature': None, 'vipRights': {'associator': {'vipCode': 100, 'rights': True}, 'musicPackage': None, 'redVipAnnualCount': -1}, 'eventCount': 0, 'playlistCount': 3})

(35****22, {'py': 'x******jl-_', 'time': 150941******9, 'userId': 35******2, 'mutual': False, 'followed': False, 'accountStatus': 0, 'nickname': '醒*****家了-_', 'avatarUrl': 'http://p1.music.126.net/KcAVTPDSC8MrKaFB9_Vd9g==/109951163985306640.jpg', 'gender': 1, 'expertTags': None, 'experts': None, 'followeds': 4, 'remarkName': None, 'follows': 9, 'authStatus': 0, 'userType': 0, 'vipType': 0, 'signature': '身邪不怕影子正', 'vipRights': None, 'eventCount': 0, 'playlistCount': 7})

#python #网易云音乐 #爬虫

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值