1

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

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

我的第一个问题是:

  1. 像这样的 url 是否不会完全破坏本地和共享的缓存机会(REST 中的可缓存约束)?我想像这样的 url 唯一有效的缓存是 WebObjects 服务器本身。
  2. 可寻址性不是也被破坏了吗?每个资源都有一个唯一的端点,但它不断变化。此外(我认为)WebObjects 也会使太旧的 URL 无效,因为它们在一段时间后“超时”。我不确定这是否仅适用于带有会话的 url。

关于抓取,我不确定是否可以从网站中提取任何有意义的端点。例如,对于一个普通的网站,我会查看 HTML 并提取 POST url,然后通过直接发布到它们而不是通过正常的请求-响应周期在我的爬虫中使用它们。

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

如果不可能,那将是一个好方法吗?我能想到的唯一选择是:

  • 使用成熟的浏览器客户端与网站交互(例如 WatiR 或 Selenium)并从响应中提取和处理 HTML
  • 手动提取动态端点,首先请求它们所在的页面,然后在 HTML 中找到它们所在的位置。然后在之后使用它们,就好像它们是“静态的”一样。

我对如何处理这种情况的意见很感兴趣,因为我认为上述任何解决方案都不是特别好的。

4

2 回答 2

1

你问了很多问题,我会看看我能否依次回答每个问题。

像这样的 url 是否不会完全破坏本地和共享的缓存机会(REST 中的可缓存约束)?我想像这样的 url 唯一有效的缓存是 WebObjects 服务器本身。

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

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

嗯,是的,从表面上看,这是真的。您已经给出了一个组件操作 URL 作为示例,它们与会话相关联。

此外(我认为)WebObjects 也会使太旧的 URL 无效,因为它们在一段时间后“超时”。我不确定这是否仅适用于带有会话的 url。

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

在这一点上,让我快速转移一下。我假设您不是 WebObjects 应用程序的所有者——您正在谈论必须抓取 WebObjects 应用程序,并且您已经确定了该特定应用程序不符合 REST 原则的一些方式。您完全正确——完全基于组件操作的 WebObjects 应用程序不会是 RESTful。WebObjects 比 REST 早了几年。话虽如此,WebObjects 应用程序可以通过多种方式完全实现RESTful:

  • 使用无会话直接操作会提供一定程度的类似 REST 的行为,并且肯定会解决您在缓存、可寻址性和过期方面发现的问题。
  • 使用ERREST 框架创建 100% RESTful 应用程序。

当然,如果您只是想抓取遗留应用程序,这些都不会帮助您。

关于抓取,我不确定是否可以从网站中提取任何有意义的端点。例如,对于一个普通的网站,我会查看 HTML 并提取 POST url,然后通过直接发布到它们而不是通过正常的请求-响应周期在我的爬虫中使用它们。

同样,如果它是一个完全基于操作的组件应用程序,那么您是对的——所有这些 URL 都是动态生成的,对您来说毫无用处。

在这种情况下,我显然不能使用从 HTML 中提取的任何 URL,因为它们是在每个请求上动态生成的,但是我读到了一些关于如果安全设置未设置为不允许这样做的情况下能够直接访问 WebObjects 组件的内容……</p>

这是关于让组件直接从其模板渲染,但有一些限制:

  • 正如您所注意到的,该应用程序可以轻松地阻止它发生。
  • 如第 53 页所述,渲染组件的用户输入和动作调用阶段被跳过,这可能意味着这种方法将仅限于渲染一个无论如何都没有任何动态内容的组件。尽管您需要知道您感兴趣的组件名称,但它们通常不会在任何地方公开,这对您的用途可能非常有限。

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

于 2014-02-19T09:18:51.870 回答
0

有点晚了,但可以提供帮助。

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

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

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

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

从理论上讲,还可以通过平板电脑或智能手机上的新 UI 控制这种闭源遗留应用程序,它将用户交互委托给后端 WebObjects 应用程序。

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

还应该可以在应用程序前面添加一个Restful接口,并通过过滤器脚本从遗留应用程序中查询数据。

于 2019-01-28T13:14:02.807 回答