从头学习爬虫(十四)实战篇----网易云音乐

本文主要介绍通过API加密参数去获取链接,那么就用网易云实战下(请认真学习前几篇,并且具备一定前端知识),如用于商业行为,概不负责。

分析过程

我们以歌单作为爬虫的入口,打开主页,随便点击一个歌单


居然没有动态加载歌单,挺好(省力),重点前面讲过的,去找请求url,而不是浏览器上面url,实际两个请求返回的信息是不一样的,有兴趣小伙伴可以试试。这个请求请求头必须加UA


然后为了获取歌单我们采用懒人方式直接审查元素,找到div,对比url,匹配出a标签href是<a href="/song?id=4175444">

id 和 歌曲名字


接着我们随便点开一个歌曲,可以看到跳转到一个界面,由于下载歌曲需要点击播放然后我们通过这个请求以流的方式接收这个MP3达到最终目的。


我们点击播放看看是哪个请求,看到media,再把请求地址复制到地址栏验证下


很好可以直接播放(注意很多时候不能这样,因为这样操作是不加refer,很多网站都需要)


既然可以下载,那我们毕竟要写进程序里,肯定要分析url

http://m10.music.126.net/20180409205446/6afa6ed5d114ca81d7dd83fcb6fc17ea/ymusic/d30d/2850/76f5/c63b817cc2876765752cd365a4cec7df.mp3

而我们唯一知道参数是id 4175444 

对这个url无所下手。由此猜想是不是一个API返回的,那么我们再去看请求


不出所料这个请求返回json里面含有播放地址,再仔细分析,一个post请求,去请求API


先看header,不知道refer 要不要,但是写死的,那我们先加上(参数调试,请学习前一篇


查看get,post参数,

get:

csrf_token 填空

post

encSecKey

params

两个参数过于复杂,请求肯定是通过js 发送ajax 。那么在发送请求前,很有可能是js 前端加密了


具体解析js过程我就浅谈可以参考别人点击打开链接

1根据参数查找哪个js里面有

core.js

2查找参数如何生成的

3用代码重新构建加密函数


那么完成两个参数。整个爬虫就完成了

代码实战

//api
		public static void api(String a) throws Exception {
			
			String detail=a;
			a=a.split(":::")[0];
			CloseableHttpClient httpclient = HttpClients.createDefault();
			CloseableHttpResponse response = null;
			//json
			//String first_param = "{rid:\"\", offset:\"offset_param\", total:\"true\", limit:\"20\", csrf_token:\"\"}";
			String first_param = "{ids:\"["+a+"]\", br: \"320000\", csrf_token:\"\"}";
			//  first_param = first_param.replace("offset_param", offset + "");
			// 参数加密
			// 16位随机字符串,直接FFF
			// String secKey = new BigInteger(100, new SecureRandom()).toString(32).substring(0, 16);
			String secKey = "FFFFFFFFFFFFFFFF";
			// 两遍ASE加密
	            String encText = aesEncrypt(aesEncrypt(first_param, "0CoJUm6Qyw8W8jud"), secKey);
	            String encSecKey = rsaEncrypt();
	            HttpPost httpPost = new HttpPost("http://music.163.com/weapi/song/enhance/player/url?csrf_token=");
	            httpPost.addHeader("Referer","http://music.163.com/" );
	            httpPost.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0" );
				List<NameValuePair> ls = new ArrayList<NameValuePair>();
				ls.add(new BasicNameValuePair("params", encText));
				ls.add(new BasicNameValuePair("encSecKey", encSecKey));
				UrlEncodedFormEntity paramEntity = new UrlEncodedFormEntity(ls, "utf-8");
				httpPost.setEntity(paramEntity);
				response = httpclient.execute(httpPost);
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					String json=EntityUtils.toString(entity, "utf-8").toString();
					System.out.println(json);
					JSONObject jsStr = JSONObject.parseObject(json);
					String json1=jsStr.getString("data").replace("[", "").replace("]", "");
					JSONObject jsStr1 =JSONObject.parseObject(json1);
				//	System.out.println(jsStr1.getString("url"));
					list2.add(detail+":::"+jsStr1.getString("url"));
				}
					response.close();
					httpclient.close();
			}
			/**
			 * ASE-128-CBC加密模式可以需要16位
			 *
			 * @param src 加密内容
			 * @param key 密钥
			 * @return
			 */
	        public static String aesEncrypt(String src, String key) throws Exception {
	            String encodingFormat = "UTF-8";
	            String iv = "0102030405060708";
	            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
	            byte[] raw = key.getBytes();
	            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
	            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
	         // 使用CBC模式,需要一个向量vi,增加加密算法强度
	            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
	            byte[] encrypted = cipher.doFinal(src.getBytes(encodingFormat));
	            return new BASE64Encoder().encode(encrypted);
	        }
	        public static String rsaEncrypt() {
	            String secKey = "257348aecb5e556c066de214e531faadd1c55d814f9be95fd06d6bff9f4c7a41f831f6394d5a3fd2e3881736d94a02ca919d952872e7d0a50ebfa1769a7a62d512f5f1ca21aec60bc3819a9c3ffca5eca9a0dba6d6f7249b06f5965ecfff3695b54e1c28f3f624750ed39e7de08fc8493242e26dbc4484a01c76f739e135637c";
	            return secKey;
	        }

贴出部分代码有需要加群313557283


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值