2010年11月5日金曜日

Webページ内をXPathで指定して抜き出して保存するなどしてみた.

追記(2010/11/07): NSThread sleepForTimeInterval:でリクエスト間隔をあけるようにしてみた.



動機
 TumblrみたいなバックアップとれればSpotlightで文字列検索できるのになぁ…。


やってみた
条件
・URLでは引数,page=%dでページが送れる
・ページ内のバックアップ単位はdiv要素とclass属性の値で指定できる.
・同div要素にはidがありバックアップが取りたい単位に対して一意である.



#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


int i, ic, j= 1;
do {
if (j>1)
[NSThread sleepForTimeInterval:30];
NSString *urlString= [NSString stringWithFormat:@"http://hoge.net/user/hoge?page=%d", j++];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];

NSXMLDocument *document = [[[NSXMLDocument alloc] initWithData:data
options:NSXMLDocumentTidyHTML
error:NULL] autorelease];

NSError *error= nil;
NSArray *nodes = [document nodesForXPath:@"//div[@class='hoge']"
error:&error];
if (error!=nil) {
NSLog(@"%@", error);
break;
}
ic= [nodes count];

for(i= 0;i<ic;i++){
NSError *err= nil;
NSXMLElement *elem= [nodes objectAtIndex:i];
NSString *idString= [[elem attributeForName:@"id"] stringValue];
NSString *content= [elem XMLStringWithOptions:(NSXMLNodePrettyPrint|NSXMLNodeCompactEmptyElement)];
NSMutableString *outputString= [NSMutableString stringWithString:@"<html>"];
[outputString appendString:@"<head>"];
[outputString appendString:@"<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>"];
[outputString appendString:@"<base href='http://hoge.net/'>"];
[outputString appendString:@"</head>"];
[outputString appendFormat:@"<body>\n%@\n</body>", content];
[outputString appendString:@"</html>"];
[outputString writeToFile:[NSString stringWithFormat:@"/path/to/backup/%@.html", idString]
atomically:YES
encoding:NSUTF8StringEncoding
error:&err];
if (err!=nil) {
NSLog(@"%@", err);
break;
}
}
} while (ic>0);

[pool drain];
return 0;
}





気がついたこと
 divのclassの値の末尾に空白が並んでいるサイトであったがこの空白はXPathで指定する際は削ってあげないと一致として扱われなかった.

0 件のコメント: