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

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

分析过程

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

从头学习爬虫(十四)实战篇----网易云音乐_第1张图片

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

从头学习爬虫(十四)实战篇----网易云音乐_第2张图片

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

id 和 歌曲名字

从头学习爬虫(十四)实战篇----网易云音乐_第3张图片

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

从头学习爬虫(十四)实战篇----网易云音乐_第4张图片

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

从头学习爬虫(十四)实战篇----网易云音乐_第5张图片

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

从头学习爬虫(十四)实战篇----网易云音乐_第6张图片

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

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

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

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

从头学习爬虫(十四)实战篇----网易云音乐_第7张图片

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


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

从头学习爬虫(十四)实战篇----网易云音乐_第8张图片

查看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 ls = new ArrayList();
				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


你可能感兴趣的:(网络爬虫)