iOS开发——网络OC篇&网络爬虫简单介绍

网络爬虫简单介绍

先来看看网络爬虫的基本原理:

一个通用的网络爬虫的框架如图所示:

网络爬虫的基本工作流程如下:

1.首先选取一部分精心挑选的种子URL;

2.将这些URL放入待抓取URL队列;

3.从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,并将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓取URL队列。

4.分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环。

以下内容均为本人个人理解。

网络数据抓取

  • 概念:网络数据抓取,也叫网络爬虫。是在我们iOS程序中,获取要抓取到的网页上的数据。
  • 用处:如果要用到某网站的一些数据,这个时候我们就要用到抓取数据技术。
  • 建议:建议抓取过程中,多利用分类,多写一些分类方法,有助于提高程序可读性,也可提高效率。

注意点:

其实网络抓取数据很简单,但是有用到正则表达式,这个有人说难,有人说很难,有人说非常难,其实我们抓取数据只会用到“." 、"*"、"?"这三个符号!

正则表达式中:“.”是包括任何字符不包括换行符,“*”是任意多个的字符,“?”是指到最近的一个URL,如果没有就是到最远的一个!

1 NSString *pantten = [NSString stringWithFormat:@"<ul class=\"cs_list\">(.*?)</ul>"];
2
3 NSRegularExpression *regx = [NSRegularExpression regularExpressionWithPattern:pantten options:NSRegularExpressionCaseInsensitive |NSRegularExpressionDotMatchesLineSeparators error:NULL];

其中有两个参数需要大家了解一下,很重要

NSRegularExpressionCaseinsensitive 不区分大小写

NSRegularExpressionDotMatcheLineSeparators 让“点”字符可以匹配换行符

抓数据,其实主要会写匹配字符串就行

  • (.*?)表示要抓到的内容
  • .*?表示要忽略的内容,爱是啥是啥
  • 字符串转义双引号用\转义括号用\\

在开发项目的过程,很多情况下我们需要利用互联网上的一些数据,在这种情况下,我们可能要写一个爬虫来爬我们所需要的数据。一般情况下都是利用正则表达式来匹配Html,获取我们所需要的数据。一般情况下分以下三步。

1、获取网页的html

  • 2、利用正则表达式,获取我们所需要的数据
  • 3、分析,使用获取到的数据,(例如,保存到数据库)

接下来我们分析代码:

1、获取网页的html

  对于一些网页,不需要提交Post提交数据时,我们可以简单的利用NSURL类来获取我们所需要的html,交将其转换中kCFStringEncodingGB_18030_2000格式,解决中文乱码问题。

  

 1 +(NSString*) urlstring:(NSString*)strurl{
 2     NSURL *url = [NSURL URLWithString:strurl];
 3     NSData *data = [NSData dataWithContentsOfURL:url];
 4
 5     NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
 6     NSString *retStr = [[NSString alloc] initWithData:data encoding:enc];
 7
 8     //NSLog(@" html = %@",retStr);
 9
10     return retStr;
11   }

  对于需要Post提交数据的网页,我们可以利用强大的ASIFormDataRequest类来实现,例如:

 1 +(void)getPostResult:(NSString*)startqi{
 2     ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:URLPost]];
 3
 4     [request setPostValue:startqi forKey:@"startqi"];
 5     [request setPostValue:@"20990101001" forKey:@"endqi"];
 6     [request setPostValue:@"qihao" forKey:@"searchType"];//网页的中的搜索方式
 7     [request startSynchronous];
 8
 9     NSData* data = [request responseData];
10
11   if (data==nil) {
12     FCLOG(@"has not data");
13   }
14   else{
15     NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
16     NSString *retStr = [[NSString alloc] initWithData:data encoding:enc];
17     FCLOG(@"html = %@",retStr);
18   }
19 }

这样的话,我们就通过了两种方式获取了我们所需要的html

2、分析html

  关于利用正则表达式匹配问题,我又对NSString类扩展了一个方法-(NSMutableArray *)substringByRegular:(NSString *)regular。根据传入的正则表达式,返回所有匹配的数组。

  

 1 @implementation NSString(StringRegular)
 2
 3
 4 -(NSMutableArray *)substringByRegular:(NSString *)regular{
 5
 6        NSString * reg=regular;
 7
 8       NSRange r= [self rangeOfString:reg options:NSRegularExpressionSearch];
 9
10       NSMutableArray *arr=[NSMutableArray array];
11
12       if (r.length != NSNotFound &&r.length != 0) {
13
14       int i=0;
15
16       while (r.length != NSNotFound &&r.length != 0) {
17
18       FCLOG(@"index = %i regIndex = %d loc = %d",(++i),r.length,r.location);
19
20       NSString* substr = [self substringWithRange:r];
21
22       FCLOG(@"substr = %@",substr);
23
24       [arr addObject:substr];
25
26       NSRange startr=NSMakeRange(r.location+r.length, [self length]-r.location-r.length);
27
28       r=[self rangeOfString:reg options:NSRegularExpressionSearch range:startr];
29     }
30   }
31   return arr;
32 }
33 @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];

3、分析或利用数据,在这里,我只是利用上一篇博客上所述方法简单的把这些数据保存到了数据库(sqlite3)中。

其实在这个arr数组中一条就是对应我数据库表中的一条记录,但是像td class等这些信息我是不需要的,所以再次利用正则表达式来分析NSString

 1 if (arr!=nil&&[arr count]>0) {
 2
 3       NSString *prereg=@"\\w{11}";
 4       NSString *backreg=@"(\\w{2}\\s{0,1}){8}";
 5
 6       TicketResultService *service=[[TicketResultService alloc] init];
 7       [[Sqlite3Helper Instance] openDB];
 8     for (NSString *sub in arr) {
 9
10       TicketResult* r=[[[TicketResult alloc] init] autorelease];
11
12       NSMutableArray* prearr=[sub substringByRegular:prereg];
13
14       if (prearr!=nil&&[prearr count]>0) {
15         r.sectionID=(NSString*)[prearr objectAtIndex:0];
16       }
17       else{
18         continue;
19       }
20
21       NSMutableArray *backarr=[sub substringByRegular:backreg];
22       if (backarr!=nil&&[backarr count]>0) {
23       r.result=[backarr objectAtIndex:0];
24       }
25       else{
26         continue;
27       }
28
29       if([service isExist:r.sectionID]){
30         continue;
31       }
32
33     r.type=[NSNumber numberWithInt:1];
34
35     [service addModel:r];
36
37   }
38   [[Sqlite3Helper Instance] closeDB];
39
40   [service release];
41 }

以上爬虫才算正式完成,其实,在此之前还有一个第0步,即判断设备目前的网络状态,如果没有联网的就没有必要去爬虫了,因为你也爬不到任何的数据。判断网络状态我是利用Apple官方的一个例子Reachability,网上也有很多关于这个的例子,我就不再细说了,非常感谢网上的各位大牛们提供的很好的办法,让我能更快的写出这些。

时间: 2024-10-09 21:01:27

iOS开发——网络OC篇&网络爬虫简单介绍的相关文章

iOS开发——实战OC篇&amp;环境搭建之Xib(玩转UINavigationController与UITabBarController)

iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController) 前面我们介绍了StoryBoard这个新技术,和纯技术编程的代码创建界面,本篇我们将介绍一个老的技术,但是在很多的公司或者库里面还是使用这个技术,既然如此它肯定有他的好处,至于好处这里我就不一一介绍了.在Xcode5之前是只能使用Xib或者代码的,而代码又对于很多初学者来说算是一个难题.毕竟不知道怎么下手.所以我就总结了一下这段时间自己编写程序的一个实例来说明怎么

iOS开发——实战OC篇&amp;环境搭建之纯代码(玩转UINavigationController与UITabBarController)

iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController) 这里我们就直接上实例: 一:新建一个项目singleView Controller,命名未iCocos 二:由于我们使用的纯代码实现的,所以删除其中的StoryBoard和Viewtroller的两个文件 三:新建一个继承自TabBar Controller的类,我们命名问iCocos ViewController 三:在Appdelegate的实现文件中导入刚刚

iOS开发——实用技术OC篇&amp;单例模式的实实现(ACR&amp;MRC)

单例模式的实实现(ACR&MRC) 在iOS开发中单例模式是一种非常常见的模式,虽然我们自己实现的比较少,但是,系统却提供了不少的到来模式给我们用,比如最常见的UIApplication,Notification等, 那么这篇文章就简单介绍一下,我们开发中如果想要实现单例模式要怎么去实现! 单例模式顾名思义就是只有一个实例,它确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例.它经常用来做应用程序级别的共享资源控制.这个模式使用频率非常高,通过一个单例类,可以实现在不同窗口之间传递数

iOS开发——实用技术OC篇&amp;?Invocation简单介绍

Invocation简单介绍 方法一:运行时方法:(这里在之前的文章定时器的几种方法中说过:www.cnblogs.com/iCocos/p/4694581.html) 1:创建一个签名: NSMethodSignature *singature = [NSMethodSignature signatureWithObjCTypes:"[email protected]:"]; 这里我想如果你仔细的话肯定注意到了:后面的“[email protected]:”,这里是运行时的语法在这里

iOS开发——多线程OC篇&amp;多线程详解

多线程详解 前面介绍了多线程的各种方式及其使用,这里补一点关于多线程的概念及相关技巧与使用,相信前面不懂的地方看了这里之后你就对多线程基本上没有什么问题了! 1——首先ios开发多线程中必须了解的概念: 进程 正在进行中的程序被称为进程,负责程序运行的内存分配 每一个进程都有自己独立的虚拟内存空间 线程 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 可以将耗时的执行路径(如:网络请求)放在其他线程中执行 创建线程的目的就是为了开启一条新的执行路径,运行指定的代

iOS开发——实用技术OC篇&amp;多线程整合

多线程整合 本文知识对iOS开发中多线程的一些知识整合,关于一些概念和技术问题并没有过多的介绍,如果你想了解更多请查看笔者之前写的iOS开发之多线程详解(比较完整):但是有部分涉及到之前文章中没有的技术点和常识,比如加锁的方式,面试相关的,还有一些关于GCD的高级用法,希望你能认真看完,或许可以收获到很多! http://www.cnblogs.com/iCocos/p/4553103.html http://www.cnblogs.com/iCocos/p/4553262.html ??先来看

iOS开发——控制器OC篇&amp;UINavigationController&amp;UITabBarController详解

UINavigationController&UITabBarController详解 一:UINavigationController 控制器的属性: UINavigationController以栈的形式保存子控制器 @property(nonatomic,copy) NSArray *viewControllers; @property(nonatomic,readonly) NSArray *childViewControllers; 导航控制器之间的跳转: 使用push方法能将某个控制

iOS开发——多线程OC篇&amp;(三)线程安全

线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题 问题代码: 1 // 2 // YYViewController.m 3 // 05-线程安全 4 // 5 // Created by apple on 14-6-23. 6 // Copyright (c) 2014年 itcase. All rights reserved

iOS开发——多线程OC篇&amp;(一)多线程介绍

多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过“活动监视器”可以查看Mac系统中所开启的进程 2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行 3.线程的串行 1个线程中任