我对PhantomJS很新。我希望通过操作HTML元素(例如:通过ID和触发点击获取按钮/链接)并从一个页面转到另一个页面并执行相同的操作来将PhantomJS页面自动化到网站。
我想知道的是:这实际上是一个创建并属于某个公司的网络系统,所以如果他们决定对他们的系统进行全面的重新设计,将来我的整个工作将会丢失,因为他们将使用全新的HTML结构和新的元素ID进行全新设计。 这是正确的吗?有办法解决这个问题吗?
答案 0 :(得分:1)
很可能是,您需要在重新设计后重写脚本。让我们来看一些场景,以及如何编写脚本。
如果依靠简单的CSS选择器或XPath表达式来选择要填充的输入元素或要单击的按钮,那么之后您很可能需要更改这些选择器。它并不总是必须这样,因为一些(大多数?)站点使用合理的名称属性来标记它们的输入元素。想一想用于登录的用户名和密码字段。有可能,这些被命名为"用户名"和#34;密码"甚至在非英语网站甚至重新设计之后:
寻找"规范"元件。
严格的CSS重新设计可能不会引入与当前脚本的不兼容性,但重新设计可能还包括技术更改,例如从多页Web应用程序迁移到单页Web应用程序。如果您非常依赖page.onLoadFinished
/ casper.then()
等待下一页加载到多页应用中,那么在重新设计到单页应用后,这将不再适用。您必须广泛使用waitFor()
/ casper.waitFor()
来等待特定(部分)标题或特定("规范")元素出现。完美的解决方案是setTimeout()
/ casper.wait()
具有足够大的超时,因为它根本不依赖于页面,但这当然不实用,因为你的脚本会闲置很多即使页面已满载并且所有元素都在那里。
如果您可以假设语言在重新设计期间没有发生变化(按钮标签等),您可以使用XPath表达式根据其中的文本选择元素。例如,如果搜索按钮文本没有更改,但它可能会从简单链接更改为输入元素或按钮(在任何方向上),那么您可以使用类似于此的XPath表达式:
"//*[(contains(text(), 'yourText') and (local-name()='a' or local-name='button')) or (local-name()='input' and contains(@*, 'yourText'))]"
您可以使用page.evaluate()
内的document.evaluate()
轻松地通过XPath选择元素。 CasperJS提供了一个XPath帮助程序实用程序(require('casper').selectXPath
)。几乎所有使用选择器的CasperJS函数都处理CSS选择器以及XPath表达式。
如果您正在刮表,那么您可以通过不依赖表结构来完成更多工作,而是编写一些启发式来检测表,即使它是由div和spans组成的。这样做很复杂,如果将来某个时候重新设计可能会发生这种情况,可能会做得太过分。
重新设计仍然可能会改变页面结构,例如将单个页面拆分为多个页面,而您实际上无法提前做任何事情。
答案 1 :(得分:1)
前段时间我和CasperJS / PhantomJS有同样的问题。目前我分裂了我的casperjs-tests
使用此结构,您只需更新配置文件中的选择器(如果没有站点功能更改)。如果您喜欢该结构,只需查看页面对象模式。 即使重新设计发生,这种测试结构的维护也非常简单。