上文中提到,Watir运用xpath在实际运用时遇到了一些问题导致无法继续。具体问题是:使用Watir with Xpath来进行脚本编写,然而首次尝试就出现问题。很简单的一段脚本却总是抛异常,脚本代码如下:
异常详见附图一,从异常信息分析,是REXML解析网页时出错,同样的脚本换成英文网页却运行正常,问题似乎是在Watir使用的REXML对中文网页的支持上。网上搜索到相关的信息也很少,Watir中运用Xpath似乎对我们日常的脚本工作失去了意义。百般无奈之下发了求助帖,希望有人能研究过类似问题。
下班之前看到回帖说Watir中的解析器正在由REXML向Nokogiri转变,也许会在Watir下一版本中体现。等到新版本已不知何年何月,于是决定自己做尝试改造一下Watir。
首先gem安装Nokogiri:gem install nokogiri
然后从异常信息定位到Watir使用Xpath时调用的方法都在ie-class.rb文件中:
#Functions written for using xpath for getting the elements.
#get the Rexml object
Rexml_document_object
#create rexml object if it is nil
Create_rexml_document_object
#output error xml when exception caught
Output_rexml_document
#return the first element that match the xpath
Element_by_xpath
#execute xpath and return an array of elements
Elements_by_xpath
很直接的思路是将使用Rexml的地方通通替换为Nokogiri,确定方向之后就开始动手。将以上方法替换为以下方法:
# Functions written for using xpath for getting the elements.—–using nokogiri
#返回nokogiri文本对象,若对象为空,则创建
def xmlparser_document_object
if @xml_parser_doc == nil
create_xml_parser_doc
end
return @xml_parser_doc
end
# Create the Nokogiri object if it is nil. This method is private so can be called only
# from xmlparser_document_object method.
#创建文本对象
def create_xml_parser_doc
require ‘nokogiri’
if @xml_parser_doc == nil
htmlSource =”<?xml version=\”1.0\” encoding=\”UTF-8\”?>\n<HTML>\n”
htmlSource = html_source(document.body,htmlSource,” “)
htmlSource += “\n</HTML>\n”
htmlSource = htmlSource.gsub(/ /, ‘ ’)
begin
@xml_parser_doc = Nokogiri::HTML::Document.parse(htmlSource)
return @xml_parser_doc
rescue => e
output_xml_parser_doc(”error.xml”, htmlSource)
raise e
end
end
end
private :create_xml_parser_doc
def output_xml_parser_doc(name, text)
file = File.open(name,”w”)
file.print(text)
file.close
end
privateutput_xml_parser_doc
# execute xpath and return an array of elements
#使用xpath定位,返回符合条件对象元素数组
def elements_by_xpath(xpath)
doc = xmlparser_document_object
modifiedXpath = “”
selectedElements = Array.new
doc.xpath(xpath).each do |element|
modifiedXpath = element.path # element = a REXML element
temp = element_by_absolute_xpath(modifiedXpath) # temp = a DOM/COM element
selectedElements << temp if temp != nil
end
#puts selectedElements.length
if selectedElements.length == 0
return nil
else
return selectedElements
end
end
将原先的Elements_by_xpath注释掉,再运行那段代码,脚本可以正常运行,至此,Watir可以将Xpath运用于中文页面啦~山寨版Rexml=>Nokogiri改造完毕,至于本系列高级篇会是什么内容,也许是等Watir新版本出来再去解读它的Parser部分源码吧~
P.S.本山寨版本若使用时遇到各类问题,请积极联系芷兰。
附图一:异常信息截图