在试用了几种不同的方法来提取网站数据后,我开发了这个看起来效果很好的简单快速的解决方案:
int zip = 13153;
int lowerBound = 10000;
int upperBound = 99999;
bool foundValidZip;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
while (foundValidZip == false) {
zip = lowerBound + arc4random() % (upperBound - lowerBound);
// Do any additional setup after loading the view, typically from a nib.
NSString *urString = [NSString stringWithFormat:@"http://www.zip-info.com/cgi-local/zipsrch.exe?zip=%i&Go=Go",zip];
NSURL *URL = [NSURL URLWithString:urString];
NSData *data = [NSData dataWithContentsOfURL:URL];
// Assuming data is in UTF8.
NSString *html = [NSString stringWithUTF8String:[data bytes]];
NSLog(@"%@",html);
NSMutableArray *names = [self stringsBetweenString:@"</th></tr><tr><td align=center>" andString:@"</font></td>" andText:html];
NSMutableArray *states = [self stringsBetweenString:@"</font></td><td align=center>" andString:@"</font></td><td align=center>" andText:html];
if ([names count] > 0 && [states count] > 0) {
NSString *name = [names objectAtIndex:0];
NSString *state = [states objectAtIndex:0];
self.nameLabel.text = name;
self.stateLabel.text = state;
self.zipLabel.text = [NSString stringWithFormat:@"%i",zip];
foundValidZip = true;
}
else {
foundValidZip = false;
}
}
}
-(NSMutableArray*)stringsBetweenString:(NSString*)start andString:(NSString*)end andText:(NSString*)text {
NSMutableArray* strings = [NSMutableArray arrayWithCapacity:0];
NSRange startRange = [text rangeOfString:start];
for( ;; )
{
if (startRange.location != NSNotFound)
{
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [text length] - targetRange.location;
NSRange endRange = [text rangeOfString:end options:0 range:targetRange];
if (endRange.location != NSNotFound)
{
targetRange.length = endRange.location - targetRange.location;
[strings addObject:[text substringWithRange:targetRange]];
NSRange restOfString;
restOfString.location = endRange.location + endRange.length;
restOfString.length = [text length] - restOfString.location;
startRange = [text rangeOfString:start options:0 range:restOfString];
}
else
{
break;
}
}
else
{
break;
}
}
NSLog(@"%@",strings);
return strings;
}
本质上,这是在查询一个网站,该网站查找与邮政编码关联的城市,然后获取随机邮政编码的 HTML。然后,该程序通过在一组独特的前端和后端“大写字母”之间搜索文本,从该 HTML 数据中提取特定的信息位。我已经将这种“上限”方法用于其他一些示例应用程序。其中一些实际上并不查询网站,而是从经常更新的静态 URL 中获取数据。我在这里看到的唯一缺陷之一是,如果 HTML 发生变化,这可能不起作用。但除此之外,它似乎工作得很好并且非常快。在我发布我的任何应用程序之前,我想确保大量查询不会损坏网站,或者对我和网站管理员造成其他不利影响。这样可以吗?还有更好的选择吗? (不是为了这个特定目的 - 邮政编码 - 但只是为了一般的拉动)
最佳答案
您正在做的事情称为抓取网站/页面。这是一种通用方法,但并不理想,并且存在许多陷阱......
一般来说,您最好不要在应用程序中包含任何抓取代码,因为如果网站发生更改并且您需要更新,您的应用程序将需要相当长的时间才能更改并重新部署到商店。
因此,最好让您自己的服务器进行抓取,然后向应用程序提供“经过净化”的数据版本,或者使用可重新配置的第三方服务(例如 Kimono ,我已经从未使用过它,但该网站是丰富多彩的)从本质上抽象您的应用程序。
对于用户而言,您的应用/服务就像普通用户一样,因此网站需要能够处理一般用户数量。
我同意 @paulw11 关于合法性的评论,如果您不拥有相关网站/与相关网站没有关系 - 您应该与他们有关系......
关于html - 这是从 iOS 上的网站提取数据的合法/安全方式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29065353/