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,那么第三方程序集必须被复制到您自己的应用程序的文件夹中。