轉:關聯函數

一.關聯操做的條件php

客戶端須要從服務端返回的數據中獲取部分數據,並將這部分數據處理後做爲本身下一次請求的一部分發出。html

那麼什麼地方須要關聯呢?
凡是腳本每次執行時都必須得到惟一標識的地方都須要關聯。假如腳本須要關聯,若是不作關聯是不會執行經過的,也就是說會有錯誤消息發生。不過很遺憾,並無任何特定的錯誤消息和關聯是有關係的。會出現什麼錯誤消息,與系統實際的錯誤處理機制有關。錯誤消息有可能會提醒用戶要從新登陸,可是也可能直接就顯示HTTP 404的錯誤消息。 web

 

二.如何找出要關聯的數據呢ajax

簡單地說,每一次執行時都會變更的值,就有可能須要作關聯。正則表達式

如:序列號和隨機數通常須要關聯。express

 常見的須要關聯的情景:json

1.登陸操做數組

2.先查後修改,先查後刪除瀏覽器

3.併發控制:防止兩個用戶同時修改或同時刪除一條記錄服務器

 

三.通常關聯操做的步驟

  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。

選項:

  • Parameter Name

此處設置存放參數的名稱,關聯出來的內容將會存放在該參數中。這裏受到Ordinal選項的影響。 

設置Parameter Name爲temp,當對應的Ordinal選項是任意一個數字的時候,只會關聯一個匹配的記錄,關聯值將會存放在temp這個參數中。當Ordinal是All的時候,關聯成功後的值將會依次存放在「temp_數字」這樣的參數數組中,而且還會添加一個temp_count的參數存放關聯出來的記錄條數。

  • Left Boundary

此處設置左邊界,這裏是用來填寫關聯對於數據處理的左匹配內容規則。

注意:若是輸入的內容裏面有雙引號,那麼須要經過轉義符\來進行處理,例如:

web_reg_save_param_ex(
"ParamName=test",
"LB=\"左邊界",
"RB=",
SEARCH_FILTERS,
LAST);

  • Match case

默認狀況下邊界是Match case的,也就是檢查大小寫的,能夠取消下面的選項來忽略大小寫檢查,會看到函數變爲如下形式:

web_reg_save_param_ex(

"ParamName=test",

"LB/IC=左邊界",

"RB=",

SEARCH_FILTERS,

LAST);

  • Binary data

若是須要關聯的內容是非ASCII字符的,那麼須要使用該選項。選中該選項後能夠看到函數變爲如下形式:

web_reg_save_param_ex(

"ParamName=test",

"LB/BIN=\\x3F\\xDD",

"RB=",

SEARCH_FILTERS,

   LAST);

  • Regular expression

該功能由函數web_reg_save_param_regexp實現。

  • Right Boundary

此處設置右邊界,這裏是用來填寫關聯時對於數據處理的右匹配內容規則,選項同左邊界。

  • DFEs

在錄製選項和回放選項中咱們提到過了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);

  • Ordinal

這個關鍵字在不少函數裏面都有應用,在這裏能夠填寫任意一個整數,也能夠填All。若是填寫數字,那麼說明從返回的記錄中取出對應順序的值,而填寫All的話將會返回全部的內容。

 當使用Ordinal =All時,關聯函數會把全部匹配過濾策略的記錄都抓出來,因爲參數只能存放一條記錄,因此關聯函數會生成一個參數數組。被關聯的記錄會以{關聯參數名_關聯id}的形式生成參數列表,而且在最後會有一個{關聯參數名_count}的參數來存放被關聯到的記錄條數。

  例如,上面寫過的一個關聯熱搜關鍵字的例子,代碼以下所示:

web_reg_save_param_ex(

"ParamName=hotsearch",

"LB=<a href=\"searcher.php?keyword=",

"RB=&type=thread\">",

SEARCH_FILTERS,

LAST);

  當Instance設置爲All時,代碼變爲:

web_reg_save_param_ex(

"ParamName=hotsearch",

"LB=<a href=\"searcher.php?keyword=",

"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".

  • Save Offset

設置關聯的內容偏移量,從第幾位開始進行關聯操做。回到最開始的例子,咱們抓取的是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:<br>",

        "RB=</b><p>",

        "Ordinal=1",

        "SaveOffset=9",

        SEARCH_FILTERS,

        "ContentType=text/html",

                    LAST);

  • Save Length

關聯出來的內容所須要保存的長度。在Save Offset的例子中咱們寫到如何得到successfully installed XAMPP on this system!這個字符串,若是咱們還但願得到這個字符串中的successfully installed XAMPP,那麼能夠再添加Save Length爲22,代碼變爲:

web_reg_save_param_ex(

        "ParamName=temp",

        "LB=Congratulations:<br>",

        "RB=</b><p>",

        "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"

 

  • Warm if text was not found (Default is Error)

若是關聯的對象不存在,又該如何進行處理呢?默認值爲Error,默認狀況下若是沒有關聯到任何內容則提示錯誤。

  • Filters

下面的選項都是幫助關聯返回限定的,經過這些設置能夠進一步減小返回的範圍。

  • Scope

該項設置關聯查詢的範圍,在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

這個選項是專門針對框架結構的網站設計的,有些時候須要關聯的內容是在某個框架中的,這個時候就須要說明所關聯的頁面是框架中的哪個了。

  • Ignore Redirection

在某些狀況下系統會使用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代碼:

<tr class="tr3">

            <td class="icon tac"><input type="checkbox" autocomplete="off" name="tidarray[]" id=tid_1884 value="1884" onclick="postManage.show

('postbatch','a_ajax_1884')" /><a title="開放主題" href="read.php?tid=1884" target="_blank"><img src="images/wind85/thread/topicnew.

gif" align="absmiddle"></a>

</td>

            <td class="subject" id="td_1884">

 

<a href="read.php?tid=1884" name="readlink"  id="a_ajax_1884" class= "subject_t f14">須要使用正則表達式關聯的例子</a>   

<img src="images/wind85/file/new.gif" align="absmiddle" title="新帖標誌" alt="新帖標誌" />

            </td>

            <td class="author"><a href="u.php?uid=1">admin</a><p>2011-10-05 </p></td>

            <td class="num"><em>0</em>/2</td>

            <td class="author"><a href="u.php?username=admin">admin</a><p> <a href="read.php?tid=1884&page=e#a" title="2011-10-05 13:43">4秒前 <span>

»</span></a></p></td>

        </tr>

在這個代碼中咱們須要關聯的正文是admin,驗證的部分在於<em>0</em>,這裏的0表明沒有回覆,後面的2表明兩次閱讀。關聯的難度在於若是用回帖數做爲左邊界那麼右邊界中的閱讀數是動態數據。若是用回帖數做爲右邊界那麼左邊界中的發帖時間和用戶uid是動態數據,致使這個關聯在之前的寫法中很難實現,必需要擴展關聯後使用strtok來分離。如今使用正則表達式關聯這個問題就很是簡單了,代碼以下:

web_reg_save_param_regexp(

"ParamName=temp",

"RegExp=<em>0</em>.*\r\n.*username=(.*)\">.*</a><p>",

"Ordinal=1",

SEARCH_FILTERS,

LAST);

 

  這裏的過濾方式是使用<em>0</em>做爲左邊界而後拼接任意內容接回車換行符,再接任意字符至username=處,關聯這串內容的右側到">位置後面接任意字符,再接</a><p>。經過這個關聯就能夠獲得未回帖的發帖人名了,另一種使用回帖數爲0做爲右邊界的寫法爲:

web_reg_save_param_regexp(

  "ParamName=temp",

  "RegExp=uid=.*\">(.*)</a><p>.*\r\n.*<em>0</em>",

  "Ordinal=1",

  SEARCH_FILTERS,

  LAST);

 

  剛開始寫的時候你們會困惑在正則表達式的編寫上,多多嘗試(注意\r\n\b回車符、換行符及空格這是開始最難處理的東西),而且合理應用常見的正則表達式驗證工具,就能夠逐漸上手,成爲你關聯應用時的神器。

  若是想要得到一個沒有回覆帖子的帖子編號,正則表達式爲:

web_reg_save_param_regexp(

"ParamName=topicid",

"RegExp=ajax_(.*)\" class.*\r\n.*\r\n.*\r\n.*<em>0</em>",

"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=<em>0</em>",

"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格式中的結構。經過這個關聯咱們能夠從:

<?xml version="1.0"?>

<t><book><auther>cloud</auther></book><book><auther>cloudB</auther></book></t>

  這樣的服務器返回中獲得如下結果:

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 空字符

相關文章
相關標籤/搜索