使用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。

例如,假设webViewUIWebView实例, username是用户名input字段:

 NSString * usernameScript = @"document.getElementById('username').value='Gabriele';"; [self.webView stringByEvaluatingJavaScriptFromString:usernameScript]; 

上面的代码将在用户Gabriele中插入Gabriele

沿着相同的path,您可以轻松地进行并通过JavaScript注入自动与网页进行交互。

一旦你login,你可以监视当前的URL,直到redirect到达你想要的点。 为了做到这一点,你必须实现UIWebViewDelegatewebViewDidFinishLoad:方法,每次Web视图加载页面时都会调用这个方法

 - (void)webViewDidFinishLoad:(UIWebView *)webView { NSURL * currentURL = webView.request.mainDocumentURL; if ([currentURL.absoluteString isEqual:desideredURLAddress]) { [self performScraping]; } } 

此时您可以执行实际的抓取。 假设你想得到一个id标签为foodiv标签的内容。 这和做一样简单

 - (void)performScraping { NSString * fooContentScript = @"document.getElementById('foo').innerHTML;"; NSString * fooContent = [self.webView stringByEvaluatingJavaScriptFromString:usernameScript]; } 

这会将div#fooinnerHTML内容存储在fooContentvariables中。

底线,在UIWebView注入JavaScript,你可以控制和刮除任何网页。

为了额外的乐趣,您可以在屏幕外执行所有这些操作。 为此,分配一个新的UIWindow并将UIWevView添加为其子视图。 如果你从来没有使UIWindow可视化,上述所有内容都将在屏幕之外发生。

请注意,这种方法非常有效,但由于您正在加载每个网页的全部内容,因此可能会耗费资源。 然而,这往往是一个必要的折衷,因为基于XMLparsing器的其他方法可能是不适当的,因为HTML页面通常是畸形的,大多数XMLparsing器只是严格地parsing它们。

在iOS或Objective-C中,你所要做的并不是特定的。 如果您知道如何处理HTTP响应,并知道如何检测您的login页面,则只需检测响应是您的login页面,就可以parsing响应并将其提交到login端点。 在开始之前,请阅读NSURLConnection的文档。