Object-c代码  
  1. //
  2. //  SougouMusicParser.h
  3. //
  4. //  Created by scott.8an@gmail.com on 12-3-13.
  5. //  Copyright (c) 2012年 littleworn llc. All rights reserved.
  6. //
  7. #import <Foundation/Foundation.h>
  8. #import "ASIHTTPRequest.h"
  9. #import "ASINetworkQueue.h"
  10. #import "TFHpple.h"
  11. #import "XPathQuery.h"
  12. #import "TFHppleElement.h"
  13. #import "DataType.h"
  14. //页面地址
  15. #define kRequestURL(s_songName,i_pageNumber) \
  16. [NSString stringWithFormat:@"http://mp3.sogou.com/music.so?pf=mp3&query=%@&page=%i&w=02009900&dr=1",s_songName,i_pageNumber]
  17. @interface SogouMusicParser : NSObject
  18. + (SogouMusicParser*)shareInstance;
  19. /**
  20. 发送成功通知的数组结构:
  21. [
  22. {
  23. "song"="save me",
  24. "artist"="Queen",
  25. "size"="4.38M",
  26. "firstChoose_url"="http://ziyuan1.myi.cn/film/YINYUE/fir/firT1563.mp3",
  27. "other_link"= [
  28. "http://mul1.tximg.cn/music/group/bbs/mp3/7/090528/1243462409315.mp3",
  29. "http://api.ning.com/files/SRIkTa2lzwqL1jt26257Yzj3TCFZ6jAJD2HaYhYB*N469JhRrd01xDttiHqjJD7K9WkWr69u6LnXChFfA2Wid0jWUfiIB33m/f.i.r._.mp3"
  30. ]
  31. },...
  32. ]
  33. **/
  34. - (void)runToGetSongInfoFromSogouWithKeyword:(NSString*)kw pageNumber:(NSInteger)pgNum;
  35. @end
Object-c代码  
  1. //
  2. //  SougouMusicParser.m
  3. //
  4. //  Created by scott.8an@gmail.com on 12-3-13.
  5. //  Copyright (c) 2012年 littleworn llc. All rights reserved.
  6. //
  7. #import "SogouMusicParser.h"
  8. NSString *const SogouMusicParseSuccessNotification = @"SogouMusicParseSuccessNotification";
  9. NSString *const SogouMusicParseFailedNotification = @"SogouMusicParseFailedNotification";
  10. static SogouMusicParser *parser_ = nil;
  11. @interface SogouMusicParser (Private)
  12. //获得跳转地址的urls
  13. /**
  14. [
  15. "http://mp3.sogou.com/down.so?gid=11950F9C68D7EDE7&globalId=1f940cf0056326c8&query=%CE%D2%C",
  16. "http://mp3.sogou.com/down.so?gid=11950F9C68D7EDE7&globalId=1f940cf0056326c8&query=%CE%D2%C",
  17. ...
  18. ]
  19. **/
  20. - (NSArray*)getJumpToDownloadPageURLsWithKeyword:(NSString*)kw pageNumber:(int)pgNum;
  21. /**
  22. 返回字典结构:
  23. {
  24. "song"="save me",
  25. "artist"="Queen",
  26. "size"="4.38M",
  27. "firstChoose_url"="http://ziyuan1.myi.cn/film/YINYUE/fir/firT1563.mp3",
  28. "other_link"= [
  29. "http://mul1.tximg.cn/music/group/bbs/mp3/7/090528/1243462409315.mp3",
  30. "http://api.ning.com/files/SRIkTa2lzwqL1jt26257Yzj3TCFZ6jAJD2HaYhYB*N469JhRrd01xDttiHqjJD7K9WkWr69u6LnXChFfA2Wid0jWUfiIB33m/f.i.r._.mp3"
  31. ]
  32. }
  33. **/
  34. - (NSDictionary*)getMusicInfoByJumpToUrl:(NSString*)jumpToUrl;
  35. @end
  36. @implementation SogouMusicParser
  37. + (SogouMusicParser*)shareInstance{
  38. if (!parser_) {
  39. parser_ = [[self alloc] init];
  40. }
  41. return parser_;
  42. }
  43. - (NSArray*)getJumpToDownloadPageURLsWithKeyword:(NSString*)kw pageNumber:(int)pgNum{
  44. if (kw && [kw length]) {
  45. //初始化需要返回的数组
  46. NSMutableArray *urlsArr = [NSMutableArray arrayWithCapacity:0];
  47. //去掉搜索条件两端空格
  48. NSString *pureKW = [kw stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
  49. //用 + 号连接需要要搜索的绑定条件
  50. NSArray *kwArr = [pureKW componentsSeparatedByString:@" "];
  51. NSMutableString *neededKw = [NSMutableString stringWithCapacity:0];
  52. if (kwArr && [kwArr count]) {
  53. for (NSString *str in kwArr) {
  54. [neededKw appendFormat:@"%@+",str];
  55. }
  56. //去掉最后一个 + 号
  57. [neededKw deleteCharactersInRange:NSMakeRange([neededKw length]-1, 1)];
  58. }else{
  59. neededKw = (NSMutableString*)kw;
  60. }
  61. //对url编码
  62. NSString *requestURLStr = kRequestURL(neededKw,pgNum);
  63. NSString *requestURLStrEnc = [requestURLStr stringByAddingPercentEscapesUsingEncoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000)];
  64. //请求页面地址
  65. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:requestURLStrEnc]];
  66. [request startSynchronous];
  67. //获得返回数据
  68. //NSString *responseStr = [request responseString];
  69. NSData  *responseData = [request responseData];
  70. //NSLog(@"%@",responseStr);
  71. if (responseData) {
  72. TFHpple *help = [TFHpple hppleWithHTMLData:responseData];
  73. if (help) {
  74. //用xpath解析获得歌曲的跳转地址
  75. //获得tbody节点
  76. NSString *xPath = @"//*[@id='songlist']";
  77. TFHppleElement *tableNode = [help peekAtSearchWithXPathQuery:xPath];
  78. TFHppleElement *tBodyNode = tableNode.firstChild;
  79. if (tBodyNode) {
  80. NSMutableArray *childrenNodes = (NSMutableArray*)tBodyNode.children;
  81. if (childrenNodes && [childrenNodes count]) {
  82. //移除第一个node
  83. [childrenNodes removeObjectAtIndex:0];
  84. for (TFHppleElement *element in childrenNodes) {
  85. NSArray *tdNodeArr = element.children;
  86. if (tdNodeArr && [tdNodeArr count]) {
  87. for (TFHppleElement *tdEle in tdNodeArr) {
  88. TFHppleElement *aNode = tdEle.firstChild;
  89. if (aNode && [[aNode objectForKey:@"action"] isEqualToString:@"down"]) {
  90. /**
  91. window.open('/down.so?gid=1A6F5F0BA3CDD9C8&globalId=137c9db3dc0bf7bf&query=%B2%BB%C3%F0%B5%C4%B0%AE&tgid=629801e642a2eadc&pf=mp3&s=%CC%B7%D3%BD%F7%EB&t=%B2%BB%C3%F0%B5%C4%B0%AE&size=4195343&ac=0&c','
  92. ','width=431,height=495,scrollbars=no');
  93. uigsPB('consume=music_down&music_down=28');return(false);
  94. */
  95. NSString *urlThatMixed = [aNode objectForKey:@"onclick"];
  96. NSArray *urlParts = [urlThatMixed componentsSeparatedByString:@"'"];
  97. //取第二个作为uri
  98. NSString *uri = [urlParts objectAtIndex:1];
  99. if (uri && [uri length]) {
  100. NSString *url = [NSString stringWithFormat:@"http://mp3.sogou.com%@",uri];
  101. //NSLog(@"组合新的跳转地址:http://mp3.sogou.com%@",uri);
  102. [urlsArr addObject:url];
  103. }
  104. }
  105. }
  106. }
  107. }
  108. if ([urlsArr count]) {
  109. return urlsArr;
  110. }
  111. }
  112. }
  113. }
  114. }else{
  115. //再次尝试
  116. [self getJumpToDownloadPageURLsWithKeyword:kw pageNumber:pgNum];
  117. }
  118. }
  119. return nil;
  120. }
  121. - (NSDictionary*)getMusicInfoByJumpToUrl:(NSString*)jumpToUrl{
  122. if (jumpToUrl && [jumpToUrl length]) {
  123. //获得下载页面,不需要编码,因为获得的数据已经是编码过了的
  124. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:jumpToUrl]];
  125. [request startSynchronous];
  126. //获得返回界面
  127. NSString *responseStr = [request responseString];
  128. NSData *responseData = [request responseData];
  129. // NSLog(@"返回下载界面的网页信息:%@",responseStr);
  130. if (responseData) {
  131. NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:0];
  132. //解析页面
  133. TFHpple *help = [TFHpple hppleWithHTMLData:responseData];
  134. /**
  135. 1.查找歌曲的下载地址
  136. **/
  137. //href="..+.mp3"
  138. NSString *pattern = @"href=\"..+.mp3\"";
  139. NSRegularExpression *exp = [NSRegularExpression regularExpressionWithPattern:pattern
  140. options:NSRegularExpressionCaseInsensitive
  141. error:nil];
  142. NSArray *metchedArr = [exp matchesInString:responseStr options:NSMatchingReportProgress range:NSMakeRange(0, [responseStr length])];
  143. if (metchedArr && [metchedArr count]) {
  144. //用数组保存其他连接
  145. NSMutableArray *otherLinksArr = [NSMutableArray arrayWithCapacity:0];
  146. for (NSTextCheckingResult *result in metchedArr) {
  147. NSRange range = result.range;
  148. NSString *urlWithHREF = [responseStr substringWithRange:range];
  149. if (urlWithHREF && [urlWithHREF length]) {
  150. NSArray *urlParts = [urlWithHREF componentsSeparatedByString:@"\""];
  151. if (urlParts && [urlParts count]>2) {
  152. NSString *musicURL = [urlParts objectAtIndex:1];
  153. //把第一个获得的地址存到首选里去
  154. NSString *songURL = [dictionary objectForKey:@"firstChoose_url"];
  155. if (!songURL || [songURL length]<1) {
  156. [dictionary setObject:musicURL forKey:@"firstChoose_url"];
  157. }else{
  158. //去重
  159. if (![musicURL isEqualToString:songURL]) {
  160. //用数组保存其他链接
  161. [otherLinksArr addObject:musicURL];
  162. }
  163. }
  164. }
  165. }
  166. }
  167. //保存其他链接到字典
  168. [dictionary setObject:otherLinksArr forKey:@"other_link"];
  169. }
  170. //如果下载地址解析失败,一下内容都没有必要存在
  171. NSString *firstChoose_url = [dictionary objectForKey:@"firstChoose_url"];
  172. if (firstChoose_url && [firstChoose_url length]) {
  173. /**
  174. 2.查找歌曲的名称
  175. **/
  176. NSString *xPath = @"//*[@class=\"info1\"]";
  177. TFHppleElement *info1Node = [help peekAtSearchWithXPathQuery:xPath];
  178. TFHppleElement *aNode = info1Node.firstChild;
  179. NSString *songName = [aNode objectForKey:@"title"];
  180. if (songName && [songName length]) {
  181. [dictionary setObject:songName forKey:@"song"];
  182. }else{
  183. [dictionary setObject:@"Unknown" forKey:@"song"];
  184. }
  185. /**
  186. 3.查找艺术家
  187. **/
  188. NSArray *info1Children = info1Node.children;
  189. if (info1Children && [info1Children count]) {
  190. BOOL isArtistTag = NO;
  191. for (TFHppleElement *node in info1Children) {
  192. if ([node.tagName isEqualToString:@"a"] && isArtistTag) {
  193. NSString *artist = [node objectForKey:@"title"];
  194. if (artist && [artist length]) {
  195. [dictionary setObject:artist forKey:@"artist"];
  196. isArtistTag =NO;
  197. }
  198. }
  199. isArtistTag = YES;
  200. }
  201. }
  202. NSString *hasArtist = [dictionary objectForKey:@"artist"];
  203. if (!hasArtist || [hasArtist length]<1) {
  204. [dictionary setObject:@"Unknown" forKey:@"artist"];
  205. }
  206. /**
  207. 4.查找歌曲的大小
  208. **/
  209. xPath = @"//*[@class=\"info2\"]";
  210. TFHppleElement *info2Node = [help peekAtSearchWithXPathQuery:xPath];
  211. NSArray *children = info2Node.children;
  212. if (children && [children count]) {
  213. for (TFHppleElement *node in children) {
  214. if ([node.tagName isEqualToString:@"strong"]) {
  215. NSString *sizeDesc = node.content;
  216. if (sizeDesc && [sizeDesc length]) {
  217. [dictionary setObject:sizeDesc forKey:@"size"];
  218. }
  219. }
  220. }
  221. }
  222. NSString *hasSize = [dictionary objectForKey:@"size"];
  223. if (!hasSize || [hasSize length]<1) {
  224. [dictionary setObject:@"Unknown" forKey:@"size"];
  225. }
  226. //NSLog(@"***************歌曲信息:%@",dictionary);
  227. //返回字典
  228. return dictionary;
  229. }
  230. return nil;
  231. }else{
  232. //重新请求,直到获取成功
  233. [self getMusicInfoByJumpToUrl:jumpToUrl];
  234. }
  235. }
  236. return nil;
  237. }
  238. - (void)runToGetSongInfoFromSogouWithKeyword:(NSString*)kw pageNumber:(NSInteger)pgNum{
  239. if (kw && [kw length]) {
  240. NSMutableArray *songsInfoArr = [NSMutableArray arrayWithCapacity:0];
  241. NSArray *songsURLsArr = [self getJumpToDownloadPageURLsWithKeyword:kw pageNumber:pgNum];
  242. //如果第一次请求失败,再次请求
  243. if (!songsInfoArr || [songsInfoArr count]<1) {
  244. songsURLsArr = [self getJumpToDownloadPageURLsWithKeyword:kw pageNumber:pgNum];
  245. }
  246. //如果第二次请求失败,再次请求
  247. if (!songsInfoArr || [songsInfoArr count]<1) {
  248. songsURLsArr = [self getJumpToDownloadPageURLsWithKeyword:kw pageNumber:pgNum];
  249. }
  250. if (songsURLsArr && [songsURLsArr count]) {
  251. for (NSString *url in songsURLsArr) {
  252. NSDictionary *songInfo = [self getMusicInfoByJumpToUrl:url];
  253. if (songInfo && [songInfo count]) {
  254. [songsInfoArr addObject:songInfo];
  255. }
  256. }
  257. }
  258. if ([songsInfoArr count]) {
  259. [[NSNotificationCenter defaultCenter] postNotificationName:SogouMusicParseSuccessNotification
  260. object:nil userInfo:[NSDictionary dictionaryWithObject:songsInfoArr forKey:@"songsInfo"]];
  261. }else{
  262. [[NSNotificationCenter defaultCenter] postNotificationName:SogouMusicParseFailedNotification
  263. object:nil userInfo:[NSDictionary dictionaryWithObject:@"This page does not exist"
  264. forKey:@"msg"]];
  265. }
  266. }else{
  267. [[NSNotificationCenter defaultCenter] postNotificationName:SogouMusicParseFailedNotification
  268. object:nil userInfo:[NSDictionary dictionaryWithObject:@"Check what you've been input"
  269. forKey:@"msg"]];
  270. }
  271. }
  272. @end

解析搜狗音乐的音乐下载地址相关推荐

  1. python爬取酷狗音乐top500_python获取酷狗音乐top500的下载地址 MP3格式

    下面先给大家介绍下python获取酷狗音乐top500的下载地址 MP3格式,具体代码如下所示: # -*- coding: utf-8 -*- # @Time : 2018/4/16 # @File ...

  2. 深度学习笔记之《解析卷积神经网络》附下载地址

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 <解析卷积神经网络>是 @魏秀参 博士撰写的深度学习实践手册,主要以卷积神 ...

  3. 耶鲁大学开放课程:《聆听音乐》6CD下载地址

    http://u.115.com/file/t4823f8780 聆听音乐CD(1-6).7z http://u.115.com/file/t493e85608 聆听音乐CD(2-6).7z http ...

  4. 移动音乐播放平台-酷狗音乐2021提供下载

    酷狗音乐2021安卓版是一款非常受欢迎的移动音乐播放平台.酷狗音乐2021app最新版采用先进的构架设计研发,设计了高传输效果的文件下载功能,实现数据分享传输.酷狗音乐2021app拥有新歌速递.权威 ...

  5. 解析邻居的耳朵音乐地址(单页下载)

    偶尔听歌的时候发现了一个很小众的音乐分享网站,邻居的耳朵,有个人的电台类型,属于音乐分享+文字分享,觉得很不错.从域名来看,属于多米旗下的网站:http://ear.duomi.com/  看来多米收 ...

  6. android下使用gson解析虾米免费音乐接口,并获取真实下载地址

    上次使用xstream解析完百度的免费音乐接口之后才发现那个接口局限性太大,无法满足需求,故又将"魔爪"伸向了虾米的音乐接口. 百度了很久,发现虾米音乐接口地址五花八门,都是能用的 ...

  7. Android获取百度音乐的音乐下载地址和歌词下载连接

    首先通过你要下载的歌曲通过下列连接: http://box.zhangmen.baidu.com/x?op=12&count=1&title={title}$${author}$$$$ ...

  8. HtmlAgilityPack.dll爬虫获取百度音乐批量下载地址(C#源码)

    关于分析的过程和思路参考原来的一篇文章 <HtmlAgilityPack 爬虫批量获取百度音乐下载地址一> http://blog.csdn.net/witch_soya/article/ ...

  9. HtmlAgilityPack 爬虫批量获取百度音乐下载地址一

    2014年8月19日15:26:16 说明:  有些网友发私信或在资源下留言问现在为什么无法抓取百度音乐排行榜了,是不是源代码有问题或代码不全面. 首先感谢你的关注,其次想说这个小工具仅仅是通过抓取百 ...

最新文章

  1. 瞄准自然语言处理,百度与鹏城实验室共建实验室
  2. 云创大会来了!全行业关心的热点都在这里
  3. git安装和使用案例
  4. 不用光驱软驱与U盘,看我如何在IBM X3500 M2服务器上用PE安装Win2K3
  5. linux下定时任务不能执行
  6. 使用 .NET CLI 构建项目脚手架
  7. 004-docker常用命令[二]-容器操作ps,top,attach,export
  8. 三种方法求最长子序列问题
  9. Qt图形界面编程入门(2)
  10. LeetCode-25:K 个一组翻转链表
  11. 【Flink】Flink 消费 kafka报错 写入 es 死信队列 FetchSessionHandler DisconnectException
  12. oracle 10g RAC app VIP ,ONS,GSD,ASM,OCR,VOTE名称及代表的涵义。
  13. Caffe学习:pycaffe利用caffemodel进行分类=批处理
  14. 新农合研究的文献外文回顾
  15. 最小行走距离(dfs+虚树)
  16. MySQL查年龄18到22的信息_Mysql查询SQL相关总结(根据生日以及身份证查询年龄以及性别区域等)...
  17. Win11如何优化服务?Win11优化服务的方法
  18. NSCalendar 日历类
  19. 深度优先搜索/广度优先搜索
  20. 新版标准日本语中级_第二十一课

热门文章

  1. Android菜单详解——子菜单(SubMenu)
  2. 数据结构笔记(期末复习,持续更新)
  3. 软件测试中的批量交易测试
  4. 学习汇编前你应该知道的知识
  5. 视频监控存储空间的算法
  6. 漩涡中的中国首富李彦宏
  7. 安利一下断言利器AssertJ
  8. C盘瘦身:通过python文件读写将qq里的缓存图片移到D盘
  9. 使用友盟快速分享与第三方登录注意事项
  10. folx是什么软件?Mac上免费的网络下载管理器