脚本之内容转换

Content Transformation


内容转换脚本用于在从网页中提取内容后转换内容。内容转换通常用于HTML元素,以提取不放在单个元素中的信息,因此不能在web浏览器中选择。例如,内容转换可以用来从包含完整地址的单个HTML元素中提取地址的某些部分,例如邮政编码。

内容转换还可以用于向内容元素中插入一个值,比如FixedValue元素。例如,可以使用内容转换脚本将项目输入参数插入到内容元素中。

您可以通过单击内容转换(Content Transformation)按钮向内容元素添加内容转换。

image.png

内容转换按钮不能用于所有内容类型,比如PageAttribute内容,但是您可以通过使用Advanced Options选项卡向这些内容类型添加内容转换。

image.png

当您点击内容转换按钮时,内容转换脚本编辑器会打开。


image.png

您可以通过输入左下角的输入文本来测试内容转换,然后单击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元素。通常,内容脚本用于在提取数据时重新组织数据。

脚本可以通过选择以下选项之一在模板中的任何地方执行。请注意,如果您在模板中首先执行脚本,那么在执行脚本时,从模板中提取的数据将不可用。

image.png
脚本选项 Script Options
Execute script last in template 在模板中提取所有内容之后,执行脚本,包括在任何子模板中定义的所有内容。
Execute script first in template 在提取模板中的任何内容之前执行脚本。
Execute script after 在特定的内容元素或模板之后执行脚本。

当您单击脚本Script按钮时,内容脚本编辑器会打开。

image.png

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操作的模板时,遵循以下这些默认步骤:

  1. 点击选择的链接或web表单按钮。
  2. 等待等待元素Wait Element从网页中消失,或者等待等待元素Wait Element的内容发生变化。如果那个时候的等待元素Wait Element在网页上不存在,那么这个步骤就会自动完成。
  3. 等待等待元素Wait Element出现在网页上。

这些默认的步骤通常很有效,但是有时您需要给Visual Web Ripper提供额外的信息,以确定异步JavaScript何时完成。例如,等待元素的内容可能会经历以下三个阶段:

  1. 等待元素Wait Element包含原始内容。
  2. 等待元素内容更改为“Loading..”。
  3. 等待元素包含新内容。

异步JavaScript调用在等待元素Wait Element包含新内容之前没有完成,但是Visual Web Ripper不理解“Loading…”文本,所以它认为这是它需要等待的新内容。Visual Web Ripper过早地停止等待异步JavaScript调用,如果您的数据提取项目从等待元素中提取内容,它将提取“Loading…”“文本而不是新内容。在这种情况下,您需要一个等待脚本,告诉Visual Web Ripper继续等待等待元素的内容发生变化,但如果内容更改为“Loading…”,则继续等待。

单击脚本等待条件Script Wait Condition按钮,将一个等待脚本添加到AJAX操作。

image.png

在您单击脚本等待条件按钮后,等待脚本编辑器将打开。

image.png

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


image.png

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中单击初始化脚本选项按钮,您可以将项目初始化脚本添加到项目中。

image.png

在您单击初始化脚本按钮后,脚本编辑器将打开。


image.png

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屏幕上显示。


image.png
image.png

与其他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窗口中向两个模板和内容元素添加条件脚本。

image.png
image.png

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。

在将输入数据源设置为脚本之后,可以将输入数据脚本添加到项目中。

image.png

image.png

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)按钮打开这个屏幕。

image.png

记住这点很重要: .NET不能从可执行文件的文件夹外部加载程序集。这意味着所有的第三方程序集应该被复制到Visual Web Ripper安装文件夹中。Visual Web Ripper不会自动将选择的程序集复制到安装文件夹。如果您使用的是Visual Web Ripper API,那么第三方程序集必须被复制到您自己的应用程序的文件夹中。
























最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 匆匆逝过的时间,谁也无法挽留,只有情感还留在那一刻,只是已经没办法重来。 偷偷进去看过你们写得东西,或许你们都不知...
    _羋小念_阅读 245评论 0 0
  • 1、 之前建立过100、200、500人的微信群,主要是以生涯规划、职场学习交流为主,定期有输出干货,但玩法设计太...
    爱之涯阅读 237评论 0 1
  • 古往今来,文人墨客对春都是情有独钟,许多绘春的古诗词脍炙人口,“野火烧不尽,春风吹又生。”让我们看到了春的生机勃发...
    写心之所想阅读 226评论 0 0