页面重新设计后,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选择器,
- 使用配置并提供所有站点功能的页面对象
- 以及使用页面对象的测试本身。
使用此结构,您只需更新配置文件中的选择器(如果站点功能没有更改)。如果您喜欢该结构,只需查看页面对象模式即可。
即使重新设计,此测试结构的维护也非常容易。
我对 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选择器,
- 使用配置并提供所有站点功能的页面对象
- 以及使用页面对象的测试本身。
使用此结构,您只需更新配置文件中的选择器(如果站点功能没有更改)。如果您喜欢该结构,只需查看页面对象模式即可。 即使重新设计,此测试结构的维护也非常容易。