使用Objective-C,login到服务并在没有API的情况下从结果页面中删除内容的最佳方式是什么?
我使用的一个服务没有API,但允许刮擦,所以我很好奇iOS / Objective-C中最好的方法是做什么:
- 获取用户login凭据
- 在网站login页面上提交
- 从结果页面抓取特定的链接
如何避免这样的问题,例如在将您带到内容网站之前,服务会将您redirect到“login成功,redirect…”页面? (这不允许您立即刮取结果页。)
例如:
像Instapaper这样的服务,如果我想访问它,而不直接使用API,例如,我将如何login,确认他们已经login,并在“login成功,redirect…”页面之后刮取内容? 甚至Twitter。
一个有效的方法是在UIWebView
执行刮取。
该策略非常简单,它涉及UIWebView
的方法stringByEvaluatingJavaScriptFromString
的使用来控制网页。
假设你已经有用户login信息,你可以使用JavaScript脚本input。
例如,假设webView
是UIWebView
实例, username
是用户名input字段:
NSString * usernameScript = @"document.getElementById('username').value='Gabriele';"; [self.webView stringByEvaluatingJavaScriptFromString:usernameScript];
上面的代码将在用户Gabriele
中插入Gabriele
。
沿着相同的path,您可以轻松地进行并通过JavaScript注入自动与网页进行交互。
一旦你login,你可以监视当前的URL,直到redirect到达你想要的点。 为了做到这一点,你必须实现UIWebViewDelegate
的webViewDidFinishLoad:
方法,每次Web视图加载页面时都会调用这个方法
- (void)webViewDidFinishLoad:(UIWebView *)webView { NSURL * currentURL = webView.request.mainDocumentURL; if ([currentURL.absoluteString isEqual:desideredURLAddress]) { [self performScraping]; } }
此时您可以执行实际的抓取。 假设你想得到一个id标签为foo
的div
标签的内容。 这和做一样简单
- (void)performScraping { NSString * fooContentScript = @"document.getElementById('foo').innerHTML;"; NSString * fooContent = [self.webView stringByEvaluatingJavaScriptFromString:usernameScript]; }
这会将div#foo
的innerHTML
内容存储在fooContent
variables中。
底线,在UIWebView
注入JavaScript,你可以控制和刮除任何网页。
为了额外的乐趣,您可以在屏幕外执行所有这些操作。 为此,分配一个新的UIWindow
并将UIWevView
添加为其子视图。 如果你从来没有使UIWindow
可视化,上述所有内容都将在屏幕之外发生。
请注意,这种方法非常有效,但由于您正在加载每个网页的全部内容,因此可能会耗费资源。 然而,这往往是一个必要的折衷,因为基于XMLparsing器的其他方法可能是不适当的,因为HTML页面通常是畸形的,大多数XMLparsing器只是严格地parsing它们。
在iOS或Objective-C中,你所要做的并不是特定的。 如果您知道如何处理HTTP响应,并知道如何检测您的login页面,则只需检测响应是您的login页面,就可以parsing响应并将其提交到login端点。 在开始之前,请阅读NSURLConnection的文档。