没有多进程,没有任何黑科技的裸爬虫。练手用,爬虫获取到的数据皆为公开且非敏感的用户信息。 目录 在GitHub上已经有网易云音乐的node.js API(GitHub:https://github.com/Binaryify/NeteaseCloudMusicApi)。根据这个库提供的信息,可以很轻易的获取到网易云音乐获取某个用户的粉丝信息接口的参数(接口限制只能获取100个),进而继续获取这100个粉丝的粉丝…简单的几层循环嵌套就能很轻易的拿到十万级到百万级的用户数据(非敏感用户信息)。 我把demo.py放到了服务器上运行,跑到程序结束大概用了24小时左右后看了一下存储的文本有50W左右的用户数据(不含敏感信息),以下用户信息为网易云公开数据,并且已经对部分数据进行打码。(已通过网易云音乐客户端私信征求用户同意) #python #网易云音乐 #爬虫
一、思路
二、参数加密流程分析
__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))
四、数据
(8****823, {'py': 'm**st', 'time': 1510*****4852, 'userId': 8******3, 'mutual': False, 'followed': False, 'accountStatus': 0, 'nickname': '名劍****收天', 'avatarUrl': 'https://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': 'https://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': 'https://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})
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算