刮刮WebObjects网站&休息

时间:2014-02-11 10:15:56

标签: rest web-scraping webobjects

我需要以编程方式与WebObjects网站进行交互,并从响应中提取数据。我正在抓取的特定WebObjects站点使用组件操作并将会话存储在cookie(而不是URL)中。这意味着所有网址都是这样的:

http://example.com/WOApp/WebObjects/WOApp.woa/wo/7.0.0.0.29.1.1.1

我的第一个问题是:

  1. 这样的网址是不是完全破坏了本地和共享缓存机会(REST中的可缓存约束)?我使用这样的URL成像唯一有效的缓存是WebObjects服务器本身。
  2. 是否也破坏了可寻址性?每个资源都有一个唯一的端点,但它会不断变化。此外(我认为)WebObjects也使得过旧的URL无效,因为它们在一段时间后“超时”。我不确定这是否仅适用于会话的网址。
  3. 关于抓取,我不确定是否可以从网站中提取任何有意义的端点。例如,对于普通网站,我会查看HTML并提取POST网址,然后通过直接发布给他们而不是通过正常的请求 - 响应周期在我的刮刀中使用它们。

    在这种情况下,我显然不能使用从HTML中提取的任何URL,因为它们是在每个请求上动态生成的,但是我读到了一些关于如果安全设置尚未设置为禁止此项,则能够直接访问WebObjects组件的内容(请参阅https://developer.apple.com/legacy/library/documentation/LegacyTechnologies/WebObjects/WebObjects_3.5/PDF/WebObjectsDevGuide.pdf,第53页“对直接请求的限制”)。我不知道如何做到这一点,或者甚至可能。

    如果不可能那么什么是好方法呢?我能想到的唯一选择是:

    • 使用完整的浏览器客户端与网站(例如WatiR或Selenium)进行互动并提取&处理回复中的HTML
    • 手动提取动态端点,首先请求它们所在的页面,然后在HTML中找到它们所在的位置。然后使用它们就好像它们是“静止的”。

    我对如何处理这种情况感兴趣,因为我不相信上述任何解决方案都特别好。

2 个答案:

答案 0 :(得分:1)

你问了很多问题,我会看看我是否可以轮流报道每一个问题。

  

这样的网址是不是完全破坏了本地和共享缓存   机会(REST中的可缓存约束)?我唯一的成像   使用此类URL进行有效缓存的是WebObjects服务器本身。

WebObjects应用程序服务器中确实存在页面缓存,您可以正确地观察到这些组件操作URL可能阻碍任何其他类型的缓存。此外,即使URL中不存在会话ID,您也需要cookie中的会话ID重新创建相同的页面,因此只需 该URL即可恢复会话来自应用程序服务器的错误。

  

是否也破坏了可寻址性?每个资源都有一个独特的   端点,但它不断变化。

嗯,是的,从表面上看,这是事实。您已经将组件操作URL作为示例,并且它们与会话绑定。

  

此外(我认为)那个   WebObjects也会使旧的URL无效,因为它们之后会“超时”   一段时间。我不确定这是否仅适用于网址   会议虽然。

再次,一切都是真的。组件操作URL生成会话,会话超时。

此时,让我快速转移一下。我假设您不是WebObjects应用程序的所有者 - 您正在谈论必须刮取WebObjects应用程序,并且您已经确定了某些特定应用程序不符合REST原则的方法。你是完全正确的 - 一个完全基于组件动作的WebObjects应用程序将不是RESTful。 WebObjects将REST早于几年。话虽如此,有些方法可以使WebObjects应用程序完全完全 RESTful:

  • 使用无会话direct actions会产生一定程度的类似REST的行为,并且肯定会解决您在缓存,可寻址性和到期时发现的问题。
  • 使用ERRest framework创建100%RESTful应用程序。

当然,如果您只是试图抓取遗留应用程序,这一切都无济于事。

  

关于抓取,我不确定是否可以提取   来自网站的任何有意义的终点。例如,正常   网站我会查看HTML并提取POST网址,然后   通过直接发布给他们而不是去我的刮刀使用它们   通过正常的请求 - 响应周期。

同样,如果它是一个完全基于组件动作的应用程序,那么你是对的 - 所有这些URL都将动态生成并且对你没用。

  

在这种情况下,我显然无法使用从HTML中提取的任何URL   因为它们是在每个请求上动态生成的,但我读过   如果能够直接访问WebObjects组件的话   安全设置尚未设置为禁止此...

这是在讨论如何直接从模板中渲染一个组件,但有一些限制:

  • 如您所知,应用程序可以轻松防止它发生。
  • 如第53页所述,跳过了渲染组件的用户输入和动作调用阶段,这可能意味着这种方法仅限于呈现一个没有任何动态内容的组件。虽然您需要知道您感兴趣的组件名称,但这通常不会在任何地方公开,这可能会对您使用非常有限。

我不确定您是否会找到比上面已经提到的高级功能方法类型更好的方法,例如在Selenium的浏览器级别自动化。如果你需要的是REST风格的应用程序资源的直接可寻址性,除非你可以重新编写应用程序以使用直接操作或ERRest,否则你不会得到它。

答案 1 :(得分:0)

有点晚了,但是可以帮上忙。

我使用Apache的mod_ext_filter(稍作修改)对WebObjects应用程序中的请求/响应进行预过滤/后过滤。该过滤器调用PHP脚本,并且可以从HTML页面读取动态超级引用和其他内容。这些脚本还可以修改HTTP请求,因此我们可以以编程方式从请求中添加/删除参数,以在旧版应用程序的前面实现新的工作流程,并在请求到达WebObjects之前清除请求。还可以在脚本中处理其他数据库,并在多个请求中存储一些内容。

因此,您可以获得动态创建的链接(可能是按钮的名称或HTML表单目标),并且可以在请求中识别这些名称。

还可以使用一些小脚本(例如,单击页面上的第三个按钮)来“远程控制”此类应用程序。您唯一需要的是DOM解析器,以获取HTML页面的结构,然后重建浏览器将要执行的操作(即,手动创建HTTP请求,并将其作为POST发送到提取的表单destination href中)。唯一的问题是Javascript代码,我们可以在PHP中对其进行分析和重新编程(即启用/禁用输入元素,因此它们不会在请求中传输)

用于Apache的WebObjects适配器模块中存在一些问题。它仍然在HTTP标头中使用Content-Length,您不能在mod_ext_filter中进行更改。如果更改请求中的HTML或参数,则内容的长度将不再匹配。但是可以改变它。

从理论上讲,也有可能通过平板电脑或智能手机上的新UI控制这种封闭源的旧版应用程序,从而将用户交互委派给后端WebObjects应用程序。

脚本取决于页面结构,因此,如果要更改WebObjects应用程序,则必须更正脚本中的某些内容(即,第三个按钮现在可以是第四个按钮)。

还应该有可能在应用程序的前面添加一个Restful接口,并通过过滤器脚本从旧版应用程序查询数据。