Content Transformation
內容轉換腳本用于在從網頁中提取內容后轉換內容。內容轉換通常用于HTML元素,以提取不放在單個元素中的信息,因此不能在web瀏覽器中選擇。例如,內容轉換可以用來從包含完整地址的單個HTML元素中提取地址的某些部分,例如郵政編碼。
內容轉換還可以用于向內容元素中插入一個值,比如FixedValue元素。例如,可以使用內容轉換腳本將項目輸入參數插入到內容元素中。
您可以通過單擊內容轉換(Content Transformation)按鈕向內容元素添加內容轉換。
內容轉換按鈕不能用于所有內容類型,比如PageAttribute內容,但是您可以通過使用Advanced Options選項卡向這些內容類型添加內容轉換。
當您點擊內容轉換按鈕時,內容轉換腳本編輯器會打開。
您可以通過輸入左下角的輸入文本來測試內容轉換,然后單擊Transform按鈕。轉換后的結果將出現在右下方的窗口中。
內容轉換可以定義為正則表達式或C#或VB.Net。當您希望從更大的提取文本中提取子文本時,經常使用正則表達式。
正則表達式
Visual Web Ripper 的正則表達式腳本可以包括任意數量的正則表達式匹配和替換操作。每個regex操作必須在兩行中指定:第一行必須包含regex模式,第二行必須包含操作,該操作可以返回、替換或插入。如果操作返回,則不需要返回(return)關鍵字。return操作將返回原始內容中的第一個匹配,或者在匹配中選擇一個組。替換操作將替換原始內容中的所有匹配,然后返回內容。insert操作將一個匹配插入指定的字符串($$必須指定為一個組,而不是使用insert時$)。
如果一個regex腳本包含多個regex操作,則下一個操作將處理前一個操作的輸出結果。
所有的正則表達式操作都是大小寫不敏感的,并且會忽略換行符。
下面的5個特殊操作應該在一行中指定:
- strip_html 從內容中刪除所有的HTML標記。
- url_decode 解碼加密的URL。
- html_decode 解碼經加密的HTML
- trim 從內容的開始和結束刪除換行符和空格。
- line_breaks 將一些HTML標簽(<p>,<br>,<li>)轉換成標準的Windows換行符。
-
to_lower 轉換文本為小寫
-to_upper 轉換文本為大寫 - capitalize_words 單詞首字母大寫于文本
語法{$content_name}
可用于在當前模板中引用提取的數據。例如,如果您有一個名為product_id的內容元素,您可以構造下面的正則表達式來提取產品ID和第一個空白區域之間的所有文本。
{$product_id}(.*?)\s
demo | description |
---|---|
.* return |
Returns the entire match, so everything in this case. 返回整個匹配,在此例子中。 |
A(.*?)B return $1 |
Returns the group 1 match, so everything between A and B. 返回組1匹配,所有的在A與B之間。 |
(A).*?(B) return $1$2 |
Returns group 1 and 2 matches, so A B in this case. 返回組1與2匹配,AB在此列中。 |
A(.*?)B replace |
Replaces every instance of everything between A and B (including A and B) with nothing. 在A與B(包含A與B)的所有實例替換為無nothing。 |
A(.*?)B replace some new text |
Replaces every instance of everything between A and B (including A and B) with "some new text". 替換一些新文本,替換A和B(包括A和B)之間的所有實例,并使用“一些新文本”。 |
A(.*?)B replace $1 |
Replaces every instance of everything between A and B (including A and B) with the text between A and B, so in effect it removes A and B. 將A和B之間的所有實例(包括A和B)替換為A和B之間的文本,因此實際上它刪除了A和B。 |
A(.?)B return $1 C(.?)D replace |
First extracts everything between A and B, and then replaces every instance of everything between C and D (including C and D) with nothing. 首先提取A和B之間的所有內容,然后替換C和D之間的所有實例(包括C和D)。 |
<br> replace \r\n |
Replaces all <BR> HTML tags with standard Windows line breaks. 用標準的Windows換行符替換所有的<BR>HTML標簽。 |
A(.*?)B return $1 url_decode |
Returns the group 1 match, so everything between A and B, and then URL-decodes the result. 返回組1匹配,所以A和B之間的所有內容,然后url_decodes結果。 |
A(.*?)B insert C$$1D |
Inserts the first match between C and D. 在C和d之間插入第一個匹配項。 |
Examples
demo | description |
---|---|
.* return |
Returns the entire match, so everything in this case. 返回整個匹配,在此例子中。 |
A(.*?)B return $1 |
Returns the group 1 match, so everything between A and B. 返回組1匹配,所有的在A與B之間。 |
(A).*?(B) return $1$2 |
Returns group 1 and 2 matches, so A B in this case. 返回組1與2匹配,AB在此列中。 |
A(.*?)B replace |
Replaces every instance of everything between A and B (including A and B) with nothing. 在A與B(包含A與B)的所有實例替換為無nothing。 |
A(.*?)B replace some new text |
Replaces every instance of everything between A and B (including A and B) with "some new text". 替換一些新文本,替換A和B(包括A和B)之間的所有實例,并使用“一些新文本”。 |
A(.*?)B replace $1 |
Replaces every instance of everything between A and B (including A and B) with the text between A and B, so in effect it removes A and B. 將A和B之間的所有實例(包括A和B)替換為A和B之間的文本,因此實際上它刪除了A和B。 |
A(.?)B return $1 C(.?)D replace |
First extracts everything between A and B, and then replaces every instance of everything between C and D (including C and D) with nothing. 首先提取A和B之間的所有內容,然后替換C和D之間的所有實例(包括C和D)。 |
<br> replace \r\n |
Replaces all <BR> HTML tags with standard Windows line breaks. 用標準的Windows換行符替換所有的<BR>HTML標簽。 |
A(.*?)B return $1 url_decode |
Returns the group 1 match, so everything between A and B, and then URL-decodes the result. 返回組1匹配,所以A和B之間的所有內容,然后url_decodes結果。 |
A(.*?)B insert C$$1D |
Inserts the first match between C and D. 在C和d之間插入第一個匹配項。 |
C# and VB.NET Scripts
內容轉換腳本必須有一個方法,如下所示。
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
//Place your transformation code here.
//This example just returns the input data
return args.Content;
}
catch (Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
public static string TransformContent(WrContentTransformationArguments args)
內容轉換方法TransformContent
必須具有準確的名稱和簽名,因此只更改方法體,而不是方法簽名。該方法接收原始內容作為參數,必須返回轉換后的內容。
WrContentTransformationArguments Properties
Name | Type | Description |
---|---|---|
Content | string | The original extracted content. |
Text | string | The inner text of the extracted element. |
HTML | string | The outer HTML of the extracted element. |
WebBrowserElement | IHTMLElement | The extracted HTML element if the WebBrowser or InternetExplorer collectors are used. This property is null if the WebCrawler collector is used. |
WebCrawlerElement | SimpleHtmlElement | The extracted HTML element if the WebCrawler collector is used. This property is null if the WebBrowser or InternetExplorer collectors are used. |
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. * See Script Utilities for more information about shared script databases. |
InputDataRow | WrDataRow | The current input data row if an input data source has been defined. * See Using an Input Data Source for more information about input data sources. |
InputParameters | WrInputParameters | Input parameters for the current project. * See Using Input Parameters for more information about input parameters. |
Examples
下面的示例展示了一個內容轉換腳本,該腳本用于將項目輸入參數分配給FixedValue內容元素。
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
return args.InputParameters[ "par1" ];
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
下面的示例提取提取的內容,并從另一個提取的元素中添加內容。請注意,其他內容必須在當前內容元素之前提取,否則在腳本運行時,內容元素將不可用。
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
return args.Content + " " + args.InternalDataRow[ "moreDescription" ];
}
catch (Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
文件名轉換
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrContentTransformationArguments.
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
return args.InternalDataRow[ "productName" ].Replace( " " , "_" );
}
catch (Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
鏈接轉換
C# and VB.NET Scripts
public static string TransformLink(WrLinkTransformationArguments args)
{
try
{
return args.Link;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
public static string TransformLink(WrLinkTransformationArguments args)
鏈接轉換方法TransformLink 必須有這個確切的名稱和簽名,所以只改變方法體,而不是方法簽名。該方法接收原始內容作為參數,并必須返回已轉換的鏈接。
Example
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrContentTransformationArguments.
public static string TransformLink(WrLinkTransformationArguments args)
{
try
{
return "/products.aspx?ID=" + args.InternalDataRow["ProductId"];
}
catch (Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
表單字段輸入轉換
C# and VB.NET Scripts
public static string TransformInput(WrInputTransformationArguments args)
{
try
{
return args.InputData;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
Examples
下面的例子顯示了一個輸入轉換腳本,該腳本用于將一個項目輸入參數分配給FormField元素。
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrInputTransformationArguments.
public static string TransformInput(WrInputTransformationArguments args)
{
try
{
return args.InputParameters[ "par1" ];
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
下一個示例顯示了一個簡單地返回當前日期的腳本。
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrInputTransformationArguments.
public static string TransformInput(WrInputTransformationArguments args)
{
try
{
return DateTime.Now.ToString("dd/MM/yyyy");
}
catch(Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error";
}
}
}
內容腳本 Content Scripts
在數據提取過程中,內容腳本用于執行定制腳本。此內容類型不會生成任何輸出數據,也不會選擇任何HTML元素。通常,內容腳本用于在提取數據時重新組織數據。
腳本可以通過選擇以下選項之一在模板中的任何地方執行。請注意,如果您在模板中首先執行腳本,那么在執行腳本時,從模板中提取的數據將不可用。
腳本選項 | Script Options |
---|---|
Execute script last in template | 在模板中提取所有內容之后,執行腳本,包括在任何子模板中定義的所有內容。 |
Execute script first in template | 在提取模板中的任何內容之前執行腳本。 |
Execute script after | 在特定的內容元素或模板之后執行腳本。 |
當您單擊腳本Script按鈕時,內容腳本編輯器會打開。
C# and VB.NET Scripts
public static void ScriptMethod(WrContentScriptArguments args)
{
try
{
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
}
}
public static void ScriptMethod(WrContentScriptArguments args)
:腳本方法ScriptMethod必須具有確切的名稱和簽名,因此只更改方法體。
Name | Type | Description |
---|---|---|
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. |
InputDataRow | WrInputDataRow | The current input data row if an input data source has been defined. |
InputParameters | WrInputParameters | Input parameters for the current project. |
WrContentScriptArguments Properties
Name | Type | Description |
---|---|---|
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. |
InputDataRow | WrInputDataRow | The current input data row if an input data source has been defined. |
InputParameters | WrInputParameters | Input parameters for the current project. |
Example
using System;
using mshtml;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrContentScriptArguments.
public static void ScriptMethod(WrContentScriptArguments args)
{
try
{
int newValue = int .Parse(args.InternalDataRow[ "value" ]);
int sum = int .Parse(args.InternalDataRow[ "sum" ]);
args.InternalDataRow[ "sum" ] = (sum + newValue).ToString();
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
}
}
}
等待腳本 Wait Scripts
許多網站使用JavaScript和AJAX請求異步更新頁面。Visual Web Ripper 常常可以鉤入AJAX請求,從而確定AJAX請求何時完成。如果Visual Web Ripper無法連接到AJAX請求,或者無法確定AJAX請求何時完成,則需要使用異步JavaScript操作。
AJAX是一個JavaScript,它執行從web瀏覽器到web服務器的異步回調。AJAX調用通常發生在用戶單擊鏈接或按鈕時。通常,他們從服務器檢索數據并在網頁上顯示。AJAX調用異步執行,從來不會加載一個全新的頁面,因此用戶不會注意到AJAX回調,除非發生在頁面上的更改。有些網站會顯示加載信息,以便通知用戶新內容正在加載。Visual Web Ripper可能無法檢測到AJAX回調,除非是在網頁上尋找變化。為了確定AJAX回調何時完成,您必須告訴Visual Web Ripper在網頁上的更改。
Visual Web Ripper需要等待一個AJAX回調來完成,這樣它就不會在新數據加載到頁面之前就開始提取數據了。
鏈接模板和FormSubmit模板可以有一個完整的頁面加載動Full page load作或JavaScript動作。如果您選擇了異步AJAX操作,您可以選擇等待元素來讓Visual Web Ripper等待,以確定何時完成了AJAX調用。等待元素可以是項目中任何其他適當的內容或模板。Visual Web Ripper等待被選擇為等待元素的HTML元素。如果您不選擇等待元素Wait Element,那么Visual Web Ripper會自動選擇鏈接中的第一個內容元素或FormSubmit模板作為等待元素Wait Element。
在打開一個具有異步JavaScript操作的模板時,遵循以下這些默認步驟:
- 點擊選擇的鏈接或web表單按鈕。
- 等待等待元素
Wait Element
從網頁中消失,或者等待等待元素Wait Element
的內容發生變化。如果那個時候的等待元素Wait Element
在網頁上不存在,那么這個步驟就會自動完成。 - 等待等待元素
Wait Element
出現在網頁上。
這些默認的步驟通常很有效,但是有時您需要給Visual Web Ripper提供額外的信息,以確定異步JavaScript何時完成。例如,等待元素的內容可能會經歷以下三個階段:
- 等待元素
Wait Element
包含原始內容。 - 等待元素內容更改為“Loading..”。
- 等待元素包含新內容。
異步JavaScript調用在等待元素Wait Element
包含新內容之前沒有完成,但是Visual Web Ripper不理解“Loading…”文本,所以它認為這是它需要等待的新內容。Visual Web Ripper過早地停止等待異步JavaScript調用,如果您的數據提取項目從等待元素中提取內容,它將提取“Loading…”“文本而不是新內容。在這種情況下,您需要一個等待腳本,告訴Visual Web Ripper繼續等待等待元素的內容發生變化,但如果內容更改為“Loading…”,則繼續等待。
單擊腳本等待條件Script Wait Condition
按鈕,將一個等待腳本添加到AJAX操作。
在您單擊腳本等待條件按鈕后,等待腳本編輯器將打開。
C# and VB.NET Scripts
public static bool IsAjaxCallCompleted(WrWaitScriptArguments args)
{
try
{
//Place your condition code here.
//This example waits until the old content has been replaced with new content,
//but waits a maximum of 3 seconds.
if (args.SecondsWaited>3)
return true ;
if (!args.OldContent.Equals(args.NewContent))
return true ;
return false ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return true ;
}
}
public static bool IsAjaxCallCompleted(WrWaitScriptArguments args)
等待腳本方法 IsAjaxCallCompleted 必須具有這個確切的名稱和簽名,所以只更改方法體,而不是方法簽名。當AJAX調用完成時,該方法必須返回true,如果尚未完成,則返回false。
*WrWaitScriptArguments Properties *
Name | Type | Description |
---|---|---|
SecondsWaited | double | The number of seconds Visual Web Ripper has waited for the AJAX call to be completed. |
OldContent | string | The content of the wait element before the AJAX call was activated. The actual content depends on the content type selected for the wait element. |
NewContent | string | The current content of the wait element. The actual content depends on the content type selected for the wait element. |
OldText | string | The inner text of the wait element before the AJAX call was activated. |
NewText | string | The inner text content of the wait element. |
OldHtml | string | The outer HTML of the wait element before the AJAX call was activated. |
NewHtml | string | The current outer HTML of the wait element. |
WaitElement | IHTMLElement | The actual wait element. Please see Microsoft documentation for the IHTMLElement for more information. |
IsOptionalWait | bool | True if the AJAX call may not change the wait element. |
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. |
InputDataRow | WrDataRow | The current input data row if an input data source has been defined. |
InputParameters | WrInputParameters | Input parameters for the current project. |
Example
面的例子展示了等待等待的等待元素的等待,直到等待的元素的內容發生變化,并且不等于“加載…”。等待腳本最多等待3秒
using System;
using mshtml;
using VisualWebRipper;
public class Script
{
public static bool IsAjaxCallCompleted(WrWaitScriptArguments args)
{
try
{
if (args.SecondsWaited>3)
return true ;
if (!args.OldContent.Equals(args.NewContent) && !args.NewContent.Equals( "Loading..." ))
return true ;
return false ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return true ;
}
}
}
頁面轉換腳本 Page Transformation Scripts
C# and VB.NET Scripts
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
return args.Content;
}
catch (Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
public static string TransformContent(WrContentTransformationArguments args)
頁面轉換方法轉換必須有準確的名稱和簽名,所以只修改方法體,而不是方法簽名。該方法接收原始內容作為參數,必須返回轉換后的內容。
Example
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
return args.Content.Replace( "class=blue_text" , "" );
}
catch (Exception exp)
{
//Place error handling here
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
項目初始化腳本Project Initialization Scripts
項目初始化腳本在數據提取項目啟動之前運行。該腳本通常用于在項目啟動之前設置項目參數,例如數據庫連接參數。
通過在Advanced Options中單擊初始化腳本選項按鈕,您可以將項目初始化腳本添加到項目中。
在您單擊初始化腳本按鈕后,腳本編輯器將打開。
C# and VB.NET Scripts
public static bool InitializeProject(WrProjectInitializeArguments args)
{
try
{
//Place your script code here.
return true ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return false ;
}
}
public static bool InitializeProject(WrProjectInitializeArguments args)
腳本方法InitializeProject必須有這個確切的名稱和簽名,所以只修改方法體,而不是方法簽名。該方法必須返回true,以指示成功或false表示失敗。
Example
下面的示例展示了一個項目初始化腳本,該腳本將項目開始URL設置為輸入參數的值。
using System;
using mshtml;
using VisualWebRipper;
public class Script
{
public static bool InitializeProject(WrProjectInitializeArguments args)
{
try
{
if (args.InputParameters.Contains( "url" ))
{
args.Project.StartUrls.Clear();
args.Project.StartUrls.Add(args.InputParameters[ "url" ]);
}
return true ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return false ;
}
}
}
API 參考API Considerations
項目初始化腳本是在運行項目之前執行的,因此,如果您正在使用這個API來運行項目,那么您的應用程序應該像這樣執行任何項目初始化腳本:
if (project.ProjectInitialize.IsEnabled)
{
project.ProjectInitialize.ExecuteProjectInitializeScript(project);
}
自定義XPath函數
每次單擊web瀏覽器中的內容時,Visual Web Ripper就會在幕后進行一些高級處理,以計算選擇XPath。XPath是一種常用的語法,用于在類似于xml的文檔中選擇元素,比如HTML文檔。Visual Web Ripper使用了XPath的定制實現,它支持XPath v1.0語法。定制的Visual Web Ripper XPath版本還支持一系列特別設計的新功能,以簡化Web抓取。除了內置函數外,還可以定義自己的自定義函數。
自定義XPath函數是通過向數據提取項目添加一個腳本來定義的。單個腳本用于定義整個項目中的所有自定義XPath函數。這個腳本可以在Advanced Options屏幕上顯示。
與其他XPath函數一樣,使用自定義XPath函數。例如:
//DIV[@id='content']/DIV[MyCustomFunction(TABLE/TR[1]/TD[1])=1]
C# and VB.NET Scripts
自定義XPath函數可以有任意名稱和任意數量的參數,但是返回類型和所有參數必須是下列類型之一:
- C#: int, double, DateTime, string, bool
- VB.NET: Integer, Double, DateTime, String, Boolean
public static bool CustomName1(WrXpathArguments args, string customArg1, bool customArg2)
{
try
{
return true ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return true ;
}
}
public static int CustomName2(string customArg1)
{
try
{
return 0;
}
catch (Exception exp)
{
return 0;
}
}
自定義XPath函數也可以有一個可選參數類型WrXpathArguments。該參數必須是函數中的第一個參數,并被自動添加到函數調用中,因此在選擇XPath時調用函數時不應指定該參數。
Name | Type | Description |
---|---|---|
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. |
InputDataRow | WrDataRow | The current input data row if an input data source has been defined. |
InputParameters | WrInputParameters | Input parameters for the current project. |
**WrXpathArguments Properties **
Name | Type | Description |
---|---|---|
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. |
InputDataRow | WrDataRow | The current input data row if an input data source has been defined. |
InputParameters | WrInputParameters | Input parameters for the current project. |
Example
using System;
using mshtml;
using VisualWebRipper;
public class Script
{
public static bool IsNotLastPage(WrXpathArguments args)
{
try
{
if (args.InternalDataRow[ "currentPage" ] == args.InternalDataRow[ "lastPage" ])
return false ;
else
return true ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return true ;
}
}
}
這個XPath函數可以用于一個Next Page導航鏈接總是顯示在頁面上,甚至在導航的最后一個頁面上。如果你使用一個分頁導航模板來處理這個導航,Visual Web Ripper就會進入一個無限循環,因為Visual Web Ripper會繼續跟隨下一頁Next Page鏈接。如果頁面顯示當前頁面索引和頁面總數,那么您可以提取該信息并使用上面的XPath函數來確保在當前頁面等于導航的最后一頁時沒有選擇下一頁Next Page面鏈接。
//A[.="Next page"][IsNotLastPage()]
XPath轉換 XPath Transformation
可以使用XPath轉換腳本轉換模板或內容元素的XPath。XPath轉換腳本是非常專業的腳本,很少使用。使用XPath函數而不是XPath轉換總是更好,因為函數更容易使用,而且提供了更大的靈活性。
XPath轉換有時可以與重復父模板結合使用。如果您正在使用一個重復父模板重復一個模板來重復多個級別的子類別鏈接,那么您可能會發現,在每個級別上的子類別鏈接都與以前的子類別級別的鏈接略有不同。當前子類別鏈接的位置可能取決于前面的子類別鏈接的位置。這對于樹菜單布局來說尤其如此。
可以將XPath轉換定義為正則表達式或C#或VB.NET腳本。c#或VB.NET腳本通常用于XPath轉換,因為它提供對一些重要屬性的訪問,這些屬性在使用正則表達式時是不可訪問的。
C# and VB.NET Scripts
XPath轉換腳本必須有一個方法,如下所示。
public static string TransformXpath(WrXpathTransformationArguments args)
{
try
{
return args.Xpath;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
public static string TransformXpath(WrInputTransformationArguments args)
XPath轉換方法TransformXpath必須具有準確的名稱和簽名,因此只更改方法體,而不是方法簽名。該方法接收原始XPath作為參數,并必須返回已轉換的XPath。
WrXpathTransformationArguments Properties
Name | Type | Description |
---|---|---|
XPath | string | The original XPath. |
ParentXpath | string | The XPath of the parent template. |
RepeatLevel | int | The number of times the same RepeatParent template has been processed. |
Project | WrProject | The current Visual Web Ripper project. |
InternalDataRow | WrInternalDataRow | The current data row containing the extracted content in the current template. |
Database | WrSharedDatabase | An open database connection. |
InputDataRow | WrDataRow | The current input data row if an input data source has been defined. |
InputParameters | WrInputParameters | Input parameters for the current project. |
Examples
下面的例子展示了一個在重復父模板上使用的XPath轉換腳本。該腳本根據父模板的XPath生成一個新的XPath。重復父模板的父模板是相同的重復父模板,所以這是一個遞歸機制。如果是第一次在遞歸循環中處理重復父模板,那么參數重復級別是1。
using System;
using VisualWebRipper;
public class Script
{
public static string TransformXpath(WrXpathTransformationArguments args)
{
try
{
if (args.RepeatLevel>1)
return args.ParentXpath + "/../UL/LI/A" ;
else
return args.Xpath;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return "Custom script error" ;
}
}
}
條件腳本 Condition Scripts
條件腳本用于在某些條件不滿足時取消數據提取。您可以取消整個模板的數據提取,也可以取消當前的內容元素。如果您取消了list模板的數據提取,您可以選擇是否應該為整個元素列表取消數據提取,還是只選擇列表中的當前元素。舉個例子,如果你有一個模板,列表遍歷一組產品鏈接,你使用一個腳本取消數據提取條件如果一個產品已經存在于您的數據庫,那么你可以選擇取消數據提取只對當前產品鏈接,而不是其他產品鏈接。
您可以在Advanced Options窗口中向兩個模板和內容元素添加條件腳本。
C# and VB.NET Scripts
public static bool IsCondition(WrConditionArguments args)
{
try
{
return true ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return true ;
}
}
public static bool IsCondition(WrConditionArguments args)
條件腳本方法IsCondition必須有這個確切的名稱和簽名,所以只修改方法體,而不是方法簽名。該方法必須返回false,以觸發條件失敗Condition fail操作。
Example
using System;
using mshtml;
using VisualWebRipper;
public class Script
{
public static bool IsCondition(WrConditionArguments args)
{
try
{
args.Database.SetSql( "select count(*) as total from product where product_code=@productCode" );
args.Database.PrepareSql();
args.Database.SetParameterTextValue( "@productCode" , args.Content);
int total = ( int ) args.Database.ExecuteScalar();
if (total == 0)
return true ;
else
return false ;
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return true ;
}
}
}
輸入數據的腳本 Input Data Scripts
一個輸入數據腳本可以用來為一個項目生成輸入值。該腳本通常用于為項目生成啟動url。如果該腳本用于生成啟動url,則必須將該項目配置為從輸入數據源提供啟動url。
在將輸入數據源設置為腳本之后,可以將輸入數據腳本添加到項目中。
C# and VB.NET Scripts
using System;
using System.Data;
using mshtml;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrInputDataScriptArguments.
public static DataTable GetInputData(WrInputDataScriptArguments args)
{
try
{
//Place your script code here.
return new DataTable();
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return null;
}
}
}
*public static bool GetInputData(WrGetInputDataArguments args)
這個腳本方法GetInputData必須有這個確切的名稱和簽名,所以只修改方法體,而不是方法簽名。該方法必須返回一個標準。包含您想要向您的項目提供的輸入數據的NET DataTable。
WrGetInputDataArguments Properties
Name | Type | Description |
---|---|---|
Project | WrProject | The current Visual Web Ripper project. |
Database | WrSharedDatabase | An open database connection. |
InputParameters | WrInputParameters | Input parameters for the current project. |
Utility Classes
Visual Web Ripper 提供了一些實用程序類,它們使創建輸入數據腳本變得更容易。
VisualWebRipper.ScriptUtils.ArrayToDataTable(string columnName, string[] values)
VisualWebRipper.ScriptUtils.ArrayToDataTable(string columnName, string stringFormat, string[] values)
ArrayToDataTable 方法是腳本類中的一個靜態方法,它可以用來將一個字符串數組轉換成一個單獨的列數據表。
VisualWebRipper.ScriptData.States.USA
USA屬性是狀態類中的一個靜態屬性,它返回一個字符串數組,其中包含了USA所有州的短名稱。
Examples
using System;
using System.Data;
using mshtml;
using VisualWebRipper;
using VisualWebRipper.ScriptData;
public class Script
{
public static DataTable GetInputData(WrInputDataScriptArguments args)
{
try
{
return ScriptUtils.ArrayToDataTable( "url" ,
"http://www.domain.com/states/{0}" , States.USA);
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return null;
}
}
}
下面的示例顯示了一個輸入數據腳本,該腳本根據數字1到1000生成一個開始url的列表。
using System;
using System.Collections.Generic;
using System.Data;
using mshtml;
using VisualWebRipper;
public class Script
{
public static DataTable GetInputData(WrInputDataScriptArguments args)
{
try
{
List<string> urls = new List<string>();
for ( int i = 1;i < 1000;i++)
{
urls.Add( "http://www.domain.com/page.php?ID=" +i.ToString());
}
return ScriptUtils.ArrayToDataTable( "url" , urls.ToArray());
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return null;
}
}
}
下面的示例與上面的示例相同,但是使用一個輸入參數來指定最大索引。
using System;
using System.Collections.Generic;
using System.Data;
using mshtml;
using VisualWebRipper;
public class Script
{
public static DataTable GetInputData(WrInputDataScriptArguments args)
{
try
{
List<string> urls = new List<string>();
int maxIndex = int .Parse(args.InputParameters[ "MaxIndex" ]);
for ( int i = 0;i < maxIndex;i++)
{
urls.Add( "http://www.domain.com/page.php?ID=" +i.ToString());
}
return ScriptUtils.ArrayToDataTable( "url" , urls.ToArray());
}
catch (Exception exp)
{
args.WriteDebug(exp.Message);
return null;
}
}
}
下面的示例從XML文件中讀取url。您需要包含assembly參考system.xml.Linq和System.Core 是為了編譯這個腳本。
public static DataTable GetInputData(WrInputDataScriptArguments args)
{
try
{
XNamespace ns = http://www.google.com/schemas/sitemap/0.84;
XDocument xmlFile = XDocument.Load(http://www.mydomain.com/myxml.xml);
var result = from r in xmlFile.Descendants(ns + "url") select r.Element(ns + "loc").Value;
string[] urls = result.ToArray();
return ScriptUtils.ArrayToDataTable("Url", urls);
}
catch(Exception exp)
{
args.WriteDebug("Custom script error: " + exp.Message);
return null;
}
}
使用第三方組件Using 3rd Party Assemblies
您可以在腳本中使用第三方程序集,但是您必須首先在項目程序集引用(Project Assembly References)屏幕上添加一個組件引用。使用管理程序集引用(Manage Assembly References)按鈕打開這個屏幕。
記住這點很重要: .NET不能從可執行文件的文件夾外部加載程序集。這意味著所有的第三方程序集應該被復制到Visual Web Ripper安裝文件夾中。Visual Web Ripper不會自動將選擇的程序集復制到安裝文件夾。如果您使用的是Visual Web Ripper API,那么第三方程序集必須被復制到您自己的應用程序的文件夾中。