页面重新设计后,PhantomJS 的页面自动化会丢失吗?

Will page automation with PhantomJS be lost after a page redesign?

我对 PhantomJS 很陌生。我想通过操纵 HTML 元素(例如:通过其 ID 获取 buttons/links 并触发点击)并从一个页面转到另一个页面并执行相同的操作,从而使用 PhantomJS 对网站进行页面自动化.

我想知道的是:这实际上是一个创建并属于某个公司的网络系统,所以 将来如果他们决定对他们的系统进行彻底的重新设计,我的整个工作都会丢失,因为它们将采用全新的设计,具有新的HTML 结构和新的元素ID。 对吗?有办法解决这个问题吗?

很可能,您需要在重新设计后重写您的脚本。让我们来看看一些场景以及您应该如何编写脚本。

如果您依靠简单的 CSS selectors 或 XPath 表达式来 select 输入要填充的元素或要单击的按钮,那么很有可能您之后需要更改 selector。它并不总是必须这样,因为一些(大多数?)站点使用合理的名称属性来标记它们的输入元素。想一想用于登录的用户名和密码字段。很有可能,即使在 non-english 演讲网站上,甚至在重新设计之后,它们也被命名为 "username" 和 "password":
寻找 "canonical" 个元素。

严格 CSS 重新设计可能不会引入与您当前脚本的不兼容性,但重新设计可能还包括技术更改,例如从 multi-page 网络应用程序迁移到 single-page 网络应用程序。如果您严重依赖 page.onLoadFinished/casper.then() to wait for the next page to load in a multi-page app, this won't work anymore after a redesign to a single-page app. You would have to extensively use waitFor()/casper.waitFor() 来等待特定(部分)标题或特定 ("canonical") 元素出现。完美的解决方案是 setTimeout()/casper.wait() 具有足够大的超时时间,因为它根本不依赖于页面,但这当然不切实际,因为即使您的脚本会闲置很多页面已完全加载,所有元素都在那里。

如果您可以假设语言在重新设计期间不会改变(按钮标签等),则可以根据元素中的文本对 select 元素使用 XPath 表达式。例如,如果搜索按钮文本没有改变,但它可能从简单的 link 变为输入元素或按钮(在任何方向),那么您可以使用类似于此的 XPath 表达式:

"//*[(contains(text(), 'yourText') and (local-name()='a' or local-name='button')) or (local-name()='input' and contains(@*, 'yourText'))]"

通过使用 page.evaluate() 内部的 document.evaluate(),您可以通过 XPath 轻松地 select 元素。 CasperJS 提供了一个 XPath 辅助工具 (require('casper').selectXPath)。几乎所有采用 selector 处理 CSS selector 以及 XPath 表达式的 CasperJS 函数。

如果你正在抓取 tables,那么你可以通过不依赖 table 结构来做更多的工作,而是编写一些启发式来检测 table 即使它由 div 和 span 组成。要做好这件事很复杂,而且这样做可能有点矫枉过正,以防将来某个时候可能会发生重新设计。

重新设计仍有可能改变页面结构,例如将单个页面拆分为多个页面,您确实无法提前进行任何操作。

前段时间我在 CasperJS/PhantomJS 遇到了同样的问题。目前我拆分了我的 casperjs-tests

  • 进入一个配置文件,其中包含已经提到的Artjom结构中的所有XPath选择器,
  • 使用配置并提供所有站点功能的页面对象
  • 以及使用页面对象的测试本身。

使用此结构,您只需更新配置文件中的选择器(如果站点功能没有更改)。如果您喜欢该结构,只需查看页面对象模式即可。 即使重新设计,此测试结构的维护也非常容易。