一.关联操做的条件php
客户端须要从服务端返回的数据中获取部分数据,并将这部分数据处理后做为本身下一次请求的一部分发出。html
那么什么地方须要关联呢?
凡是脚本每次执行时都必须得到惟一标识的地方都须要关联。假如脚本须要关联,若是不作关联是不会执行经过的,也就是说会有错误消息发生。不过很遗憾,并无任何特定的错误消息和关联是有关系的。会出现什么错误消息,与系统实际的错误处理机制有关。错误消息有可能会提醒用户要从新登陆,可是也可能直接就显示HTTP 404的错误消息。 web
二.如何找出要关联的数据呢ajax
简单地说,每一次执行时都会变更的值,就有可能须要作关联。正则表达式
如:序列号和随机数通常须要关联。express
常见的须要关联的情景:json
1.登陆操做数组
2.先查后修改,先查后删除浏览器
3.并发控制:防止两个用户同时修改或同时删除一条记录服务器
三.通常关联操做的步骤
注:对于WEB应用来讲,通常会用一个hidden的Field存放。
四.关联分为自动关联和手动关联
自动关联操做只对Web协议、DB协议和其余少数几种协议有效,对socket等协议录制的脚本不起做用。
五.关联函数web_reg_save_param_ex详解
在LR11中除了对web_reg_save_param增强为web_reg_save_param_ex,还提供了另外两个很是好用的函数web_reg_save_param_regexp和web_reg_save_param_xpath。
选项:
此处设置存放参数的名称,关联出来的内容将会存放在该参数中。这里受到Ordinal选项的影响。
设置Parameter Name为temp,当对应的Ordinal选项是任意一个数字的时候,只会关联一个匹配的记录,关联值将会存放在temp这个参数中。当Ordinal是All的时候,关联成功后的值将会依次存放在“temp_数字”这样的参数数组中,而且还会添加一个temp_count的参数存放关联出来的记录条数。
此处设置左边界,这里是用来填写关联对于数据处理的左匹配内容规则。
注意:若是输入的内容里面有双引号,那么须要经过转义符\来进行处理,例如:
web_reg_save_param_ex(
"ParamName=test",
"LB=\"左边界",
"RB=",
SEARCH_FILTERS,
LAST);
默认状况下边界是Match case的,也就是检查大小写的,能够取消下面的选项来忽略大小写检查,会看到函数变为如下形式:
web_reg_save_param_ex(
"ParamName=test",
"LB/IC=左边界",
"RB=",
SEARCH_FILTERS,
LAST);
若是须要关联的内容是非ASCII字符的,那么须要使用该选项。选中该选项后能够看到函数变为如下形式:
web_reg_save_param_ex(
"ParamName=test",
"LB/BIN=\\x3F\\xDD",
"RB=",
SEARCH_FILTERS,
LAST);
该功能由函数web_reg_save_param_regexp实现。
此处设置右边界,这里是用来填写关联时对于数据处理的右匹配内容规则,选项同左边界。
在录制选项和回放选项中咱们提到过了DFE的功能,在关联这里也支持DFE的数据处理,咱们先回到录制选项中的那个例子中,为其写一个普通关联看看返回(为了让返回结果看得更清楚,这里提早使用了Scope=BODY规则,该规则做用参考后面的Scope属性介绍)。
接着咱们使用关联的DFE功能,在这里设置关联的DFEs格式为JsonXml(这里的格式是指系统自带的DFE模块的Tag名,参考图3.35),而后还要确保Run-time settings中的DFE功能启用,代码变为:
web_reg_save_param_ex(
"ParamName=jsonresponse",
"LB=",
"RB=",
"DFEs=JsonXml",
"Ordinal=1",
SEARCH_FILTERS,
LAST);
web_url("json.php",
"URL=http://localhost:8000/phpwind85/json.php",
LAST);
这个关键字在不少函数里面都有应用,在这里能够填写任意一个整数,也能够填All。若是填写数字,那么说明从返回的记录中取出对应顺序的值,而填写All的话将会返回全部的内容。
当使用Ordinal =All时,关联函数会把全部匹配过滤策略的记录都抓出来,因为参数只能存放一条记录,因此关联函数会生成一个参数数组。被关联的记录会以{关联参数名_关联id}的形式生成参数列表,而且在最后会有一个{关联参数名_count}的参数来存放被关联到的记录条数。
例如,上面写过的一个关联热搜关键字的例子,代码以下所示:
web_reg_save_param_ex(
"ParamName=hotsearch",
"LB=
"RB=&type=thread\">",
SEARCH_FILTERS,
LAST);
当Instance设置为All时,代码变为:
web_reg_save_param_ex(
"ParamName=hotsearch",
"LB=
"RB=&type=thread\">",
"Ordinal=ALL",
SEARCH_FILTERS,
LAST);
运行代码后,关联将会返回全部匹配左右边界的内容,结果以下:
Action.c(20): Notify: Saving Parameter "hotsearch_1 = 结婚".
Action.c(20): Notify: Saving Parameter "hotsearch_2 = 母婴".
Action.c(20): Notify: Saving Parameter "hotsearch_3 = phpwind".
Action.c(20): Notify: Saving Parameter "hotsearch_4 = testing001".
Action.c(20): Notify: Saving Parameter "hotsearch_5 = 结婚".
Action.c(20): Notify: Saving Parameter "hotsearch_count = 5".
设置关联的内容偏移量,从第几位开始进行关联操做。回到最开始的例子,咱们抓取的是You have successfully installed XAMPP on this system!,若是须要得到successfully installed XAMPP on this system!这个字符串,则不用改变左边界,只须要设置Save Offset为9便可,代码为:
web_reg_save_param_ex(
"ParamName=temp",
"LB=Congratulations:
",
"RB=
",
"Ordinal=1",
"SaveOffset=9",
SEARCH_FILTERS,
"ContentType=text/html",
LAST);
关联出来的内容所须要保存的长度。在Save Offset的例子中咱们写到如何得到successfully installed XAMPP on this system!这个字符串,若是咱们还但愿得到这个字符串中的successfully installed XAMPP,那么能够再添加Save Length为22,代码变为:
web_reg_save_param_ex(
"ParamName=temp",
"LB=Congratulations:
",
"RB=
",
"Ordinal=1",
"SaveOffset=9",
"SaveLen=22",
SEARCH_FILTERS,
"ContentType=text/html",
LAST);
经过Save Length和Save Offset的设置,咱们就能够方便地抓取服务器返回的定长数据的任意一个部分了。
关联能够调整偏移量和长度,那么参数能作到吗?固然能够,若是须要对一个参数值进行偏移和长度设置,则须要使用lr_save_var函数,例如,下面的代码:
lr_save_string("I come from shanghai","city");
lr_save_var(lr_eval_string("{city}"),6,0,"result");
//从city这个参数中取6位长度的内容保存到result参数中
lr_save_var(lr_eval_string("{city}")+7,4,0,"result");
//从city这个参数的第7位开始取4个长度的内容保存到result参数中
能够看到运行的结果是:
Action.c(3): Notify: Saving Parameter "city = I come from shanghai"
Action.c(4): Notify: Saving Parameter "result = I come"
Action.c(5): Notify: Saving Parameter "result = from"
若是关联的对象不存在,又该如何进行处理呢?默认值为Error,默认状况下若是没有关联到任何内容则提示错误。
下面的选项都是帮助关联返回限定的,经过这些设置能够进一步减小返回的范围。
该项设置关联查询的范围,在LR11中和之前的范围作了一些调整,应该算是更增强大了,这里Scope提供了4个选项:Body、Headers、Cookies、All。
1)ALL
比较容易理解,就是让服务器的返回全部内容做为须要关联的目标来处理。
2)Headers/Body/Cookies
这3个选项都是从请求返回的全部内容进行关联处理,包括图片、JavaScript脚本等。区别在于对返回信息的分隔方式。在前面介绍HTTP的时候介绍过HTTP返回的内容实际上是由Header(HTTP信息头)和Body(HTTP内容)组成的,而Cookie又是Header中的一部分,在Tree模式下的HTTP View视图中能够清晰地看到LR如何定义各块内容。当咱们对Phpwind登陆返回作关联时,不一样的Scope带来的效果以下。
3)Header
指所关联的内容是全部服务器返回请求的HTTP头部份内容。能够经过查看服务器返回内容来了解,Body以前的内容都属于Header:
4)Body
就是服务器返回在Body之后的内容:
5)Cookie
指Header部分关于Cookie定义的部份内容。
Request URL
这里提供了针对URL地址的过滤方式来减小关联范围,例如,咱们能够填写*.php来讲明只对PHP页面进行过滤。
Content Type
回顾咱们在讲录制下载操做的时候,提到了Content Type这个概念,这样在录制的时候能够经过这个特性来过滤录制对象。而在关联这里,这个属性的效果是相同的,在网站应用中,咱们要关联的内容通常都存放在HTML页面中,因此这里咱们一般都是用text/html来做为Content Type过滤规则的。
Frame ID
这个选项是专门针对框架结构的网站设计的,有些时候须要关联的内容是在某个框架中的,这个时候就须要说明所关联的页面是框架中的哪个了。
在某些状况下系统会使用HTTP 3xx的重定向操做来完成页面跳转,该选项是用来忽略跳转页面信息的。若是选中该选项,经过这种重定向技术的页面将不会被关联。
有时须要配合使用web_set_max_html_param_len函数能够自定义关联返回值存放的参数的最大长度。
六.关联函数web_reg_save_param_regexp详解
在介绍这个函数前先来处理一种状况。前面关联的左右边界都是静态的,若是左右边界是动态的,而且系统返回的id是不定长度的,那么如何使用关联函数将该id取出呢?这个问题在现实状况中会常常遇到,仅仅经过一个关联函数是没法处理的,这个时候还须要使用一个函数strtok()来进行字符内容切割。
strtok()函数的做用是经过某个分隔符来切份内容的。
char temp[100];
char * token;
extern char * strtok(char * string, const char * delimiters );
lr_save_string("sessionid=54321123&action=work","param");
strcpy(temp,lr_eval_string("{param}"));//取出参数值,而且赋值给变量temp
token = (char *)strtok(temp,"&");//使用&符号做为分隔符
这个时候token="sessionid=54321123",而且是根据&符号分隔的,因此id的长度能够任意变化,而token中的sessionid能够经过关联的时候Save Offset进行处理,或者使用strtok()函数对等号再次进行处理。
而在LR11中提供了web_reg_save_param_regexp正则表达式关联,上面的写法也能够退休了。打开Add Step添加步骤,选择web_reg_save_param_regexp函数,打开设置窗口,如图所示
在这个函数中关键就是在Regular Expression的写法上,在前面XML参数的lr_xml_find函数中咱们提到过正则表达式的写法,在这里的写法惟一区别在于须要关联返回的内容须要用()圆括号标记。例如,这里的read(.*)\.php就是指全部符合read开头.php结尾中间的任何内容都关联保存到参数temp中,这里的\是转义符,确保.号可以正确地当作普通字符来匹配。
举例说明:
在Phpwind中若是咱们要关联一个没有被回复过的帖子的发帖人是谁,这个在之前是比较难于实现的,咱们先来看看一个帖子的HTML代码:
在这个代码中咱们须要关联的正文是admin,验证的部分在于0,这里的0表明没有回复,后面的2表明两次阅读。关联的难度在于若是用回帖数做为左边界那么右边界中的阅读数是动态数据。若是用回帖数做为右边界那么左边界中的发帖时间和用户uid是动态数据,致使这个关联在之前的写法中很难实现,必需要扩展关联后使用strtok来分离。如今使用正则表达式关联这个问题就很是简单了,代码以下:
web_reg_save_param_regexp(
"ParamName=temp",
"RegExp=0.*\r\n.*username=(.*)\">.*
",
"Ordinal=1",
SEARCH_FILTERS,
LAST);
这里的过滤方式是使用0做为左边界而后拼接任意内容接回车换行符,再接任意字符至username=处,关联这串内容的右侧到">位置后面接任意字符,再接
。经过这个关联就能够获得未回帖的发帖人名了,另一种使用回帖数为0做为右边界的写法为:
web_reg_save_param_regexp(
"ParamName=temp",
"RegExp=uid=.*\">(.*)
.*\r\n.*0",
"Ordinal=1",
SEARCH_FILTERS,
LAST);
刚开始写的时候你们会困惑在正则表达式的编写上,多多尝试(注意\r\n\b回车符、换行符及空格这是开始最难处理的东西),而且合理应用常见的正则表达式验证工具,就能够逐渐上手,成为你关联应用时的神器。
若是想要得到一个没有回复帖子的帖子编号,正则表达式为:
web_reg_save_param_regexp(
"ParamName=topicid",
"RegExp=ajax_(.*)\" class.*\r\n.*\r\n.*\r\n.*0",
"Ordinal=1",
SEARCH_FILTERS,
LAST);
换成strtok的写法那么就要这样写了:
char tokstr[2000];
extern char * strtok(char * string, const char * delimiters );
char * token;
web_reg_save_param("string",
"LB=a_ajax_",
"RB=0",
"Ord=1",
"Search=NoResource",
LAST);
//请求部分略
strcpy(tokstr,lr_eval_string("{string}"));
token = (char *)strtok(tokstr,"\"");
lr_output_message(token);//输出处理后获得的帖子编号
七.关联函数web_reg_save_param_xpath详解
若是你们用过一些自动化工具可能会对Xpath比较熟悉。Xpath能够经过路径的方式访问到XML、HTML的任意节点位置,在关联里也可使用这个技术来帮咱们查找须要的元素。
打开Add Step添加步骤,选择web_reg_save_param_xpath函数,打开设置窗口,如图所示。
在这里须要为Query String编写对应的Xpath查询语法,这里填写的/t/book/title是指一个XML格式中的结构。经过这个关联咱们能够从:
cloudcloudB
这样的服务器返回中获得如下结果:
Action.c(14): Notify: Saving Parameter "temp_1 = A".
Action.c(14): Notify: Saving Parameter "temp_2 = B".
Action.c(14): Notify: Saving Parameter "temp_count = 2".
对于一些比较复杂的数据格式,那么怎么编写Xpath呢?这里使用FireBug来帮助咱们,首先安装Firefox浏览器而且安装FireBug插件,接着在打开的页面中点击右下角的FireBug图标,切出该插件,所示。
接着在浏览页面中找到本身想要的内容,经过右键菜单中的Inspect Element将这个元素定位,如图所示。
接着将鼠标放到上面的工具条中,会看到对应的Xpath层次已经显示出来了,如图所示。
这里能够经过右键菜单复制当前的Xpath字符串,也能够在下面更加准确选择,如图所示。
经过这种方式不但能够获得XML的任意位置Xpath写法,还能得到HTML的任意位置Xpath。在获得Xpath后就能够直接复制到关联函数web_reg_save_param_xpath中了。可是在LR11中该关联函数只对XML数据格式有用,对于HTML格式没法使用Xpath进行定位关联,因此,在处理HTML内容时仍是推荐使用前面的两个关联函数来处理。
8、转义字符总结
在作手动关联时,取边界值的时候,会常常用到转义字符,现将转义字符整理以下:
\b 退格
\f 换页
\n 换行
\r 回车
\t 水平制表
\v 垂直制表
\\ 反斜杠
\? 问号字符
\' 单引号字符
\" 双引号字符
\0 空字符
转载:http://blog.sina.com.cn/s/blog_62079f620101a4jc.html