在开发项目的过程,不少状况下咱们须要利用互联网上的一些数据,在这种状况下,咱们可能要写一个爬虫来爬咱们所须要的数据。通常状况下都是利用正则表达式来匹配Html,获取咱们所须要的数据。通常状况下分如下三步。 一、获取网页的html 二、利用正则表达式,获取咱们所须要的数据 三、分析,使用获取到的数据,(例如,保存到数据库) 接下来咱们分析代码: 一、获取网页的html 对于一些网页,不须要提交Post提交数据时,咱们能够简单的利用NSURL类来获取咱们所须要的html,交将其转换中kCFStringEncodingGB_18030_2000格式,解决中文乱码问题。 +(NSString*) urlstring:(NSString*)strurl{ NSURL *url = [NSURL URLWithString:strurl]; NSData *data = [NSData dataWithContentsOfURL:url]; NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSString *retStr = [[NSString alloc] initWithData:data encoding:enc]; //NSLog(@" html = %@",retStr); return retStr; } 对于须要Post提交数据的网页,咱们能够利用强大的ASIFormDataRequest类来实现,例如: +(void)getPostResult:(NSString*)startqi{ ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:URLPost]]; [request setPostValue:startqi forKey:@"startqi"]; [request setPostValue:@"20990101001" forKey:@"endqi"]; [request setPostValue:@"qihao" forKey:@"searchType"];//网页的中的搜索方式 [request startSynchronous]; NSData* data = [request responseData]; if (data==nil) { FCLOG(@"has not data"); } else{ NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSString *retStr = [[NSString alloc] initWithData:data encoding:enc]; FCLOG(@"html = %@",retStr); } } 这样的话,咱们就经过了两种方式获取了咱们所须要的html 二、分析html 关于利用正则表达式匹配问题,我又对NSString类扩展了一个方法-(NSMutableArray *)substringByRegular:(NSString *)regular。根据传入的正则表达式,返回全部匹配的数组。 @implementation NSString(StringRegular) -(NSMutableArray *)substringByRegular:(NSString *)regular{ NSString * reg=regular; NSRange r= [self rangeOfString:reg options:NSRegularExpressionSearch]; NSMutableArray *arr=[NSMutableArray array]; if (r.length != NSNotFound &&r.length != 0) { int i=0; while (r.length != NSNotFound &&r.length != 0) { FCLOG(@"index = %i regIndex = %d loc = %d",(++i),r.length,r.location); NSString* substr = [self substringWithRange:r]; FCLOG(@"substr = %@",substr); [arr addObject:substr]; NSRange startr=NSMakeRange(r.location+r.length, [self length]-r.location-r.length); r=[self rangeOfString:reg options:NSRegularExpressionSearch range:startr]; } } return arr; } @end 在这种状况下,咱们首先我获得咱们要获取数据的正则表达式,关于正则表达式这种火星文我就很少说了,我也很纠结,我就很少说了,可是有一点就是,所写的正则表达式必定是咱们所须要的数据,而且可以屏蔽无效信息的,有可能在一次匹配中没法获取,能够屡次利用正则表达式来分段获取。下面是个人语句,在个人例子中,就是两次利用正则表达式。 NSString *regstr = @"<td class=\'z_bg_05\'>\\w{11}</td><td class=\'z_bg_13\'>(\\w{2}\\s{0,1})*</td>"; NSMutableArray *arr=[strhtml substringByRegular:regstr]; 三、分析或利用数据,在这里,我只是利用上一篇博客上所述方法简单的把这些数据保存到了数据库(sqlite3)中。 其实在这个arr数组中一条就是对应我数据库表中的一条记录,可是像td class等这些信息我是不须要的,因此再次利用正则表达式来分析NSString if (arr!=nil&&[arr count]>0) { NSString *prereg=@"\\w{11}"; NSString *backreg=@"(\\w{2}\\s{0,1}){8}"; TicketResultService *service=[[TicketResultService alloc] init]; [[Sqlite3Helper Instance] openDB]; for (NSString *sub in arr) { TicketResult* r=[[[TicketResult alloc] init] autorelease]; NSMutableArray* prearr=[sub substringByRegular:prereg]; if (prearr!=nil&&[prearr count]>0) { r.sectionID=(NSString*)[prearr objectAtIndex:0]; } else{ continue; } NSMutableArray *backarr=[sub substringByRegular:backreg]; if (backarr!=nil&&[backarr count]>0) { r.result=[backarr objectAtIndex:0]; } else{ continue; } if([service isExist:r.sectionID]){ continue; } r.type=[NSNumber numberWithInt:1]; [service addModel:r]; } [[Sqlite3Helper Instance] closeDB]; [service release]; } 以上爬虫才算正式完成,其实,在此以前还有一个第0步,即判断设备目前的网络状态,若是没有联网的就没有必要去爬虫了,由于你也爬不到任何的数据。判断网络状态我是利用Apple官方的一个例子Reachability,网上也有不少关于这个的例子,我就再也不细说了,很是感谢网上的各位大牛们提供的很好的办法,让我能更快的写出这些。