65.9K
CodeProject 正在变化。 阅读更多。
Home

网站抓取

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (18投票s)

2013年3月28日

CPOL

7分钟阅读

viewsIcon

93616

downloadIcon

9048

使用 Watin 进行网站抓取。

Click to enlarge image

引言

本文的主要目标是演示如何使用 Watin 测试工具等测试工具抓取网页。

通常,在 ASP.NET 中使用 C# 的 HttpWebRequest HttpWebResponse 方法来抓取网页。但是,人们注意到,当应用程序使用 AJAX 进行服务器端导航时,使用 HttpWebRequest 方法获取页面数据会变得非常困难(我们需要采取一些技巧来获取下一页数据)。

使用 Watin 工具可以非常轻松快速地完成同样的事情。我在这里的目的不是挑战 HttpWebRequest HttpWebResponse 方法,而是展示如何使用 Watin 等测试工具有效地进行网站抓取。

背景 

在本文中,我创建了一个带有类别和后续项目列表的演示网站。我将使用 Watin 等 .NET 测试工具抓取这个网站。
在这里,我使用了 NUnit、Watin 等第三方工具来演示这个例子。请参考以下每个工具的简要介绍以及进一步参考的相应 URL。

关于 Watin:Watin 是一个专为 .NET 设计的第三方 Web 应用程序测试工具。

您可以通过访问 此链接 了解更多关于此工具的信息。
关于 NUnit:NUnit 是适用于所有 .NET 语言的第三方单元测试框架。您可以通过访问 此站点 收集更多信息。

Using the Code

本文包含两个应用程序。下面提供了关于这些应用程序的简要详细信息。

第一个应用程序是在 Visual Studio 2010 (.NET 4.0) 中创建的基于 Web 的应用程序。这是一个包含类别和项目列表的演示网站。此网站需要在本地/远程服务器 IIS 上部署。

第二个应用程序是使用 Visual Studio 2010 (.NET 4.0) 和 Watin DLL 创建的基于 Windows 的类库项目。

执行此演示所需的预备软件如下:

  1. .NET Framework 4.0
  2. NUnit 2.6.2

请按照以下步骤配置 Web 应用程序:

  1. 将 Web 应用程序部署到您的 IIS 中,并为其分配 .NET Framework 4.0,然后检查该应用程序在您的工作站上是否运行正常。

执行以下操作以配置 Web 抓取应用程序:

  1. 打开此应用程序的配置文件(App.configWatinWebScraping.dll.config),并根据需要更改以下配置项的值:

演示 Web 应用程序的代码片段

下面简要介绍了相应页面上的代码。

  • CategoryListing.aspx:仅包含类别列表,形式为超链接。
  • ItemListing.aspxsting.aspx:在此页面中,我使用了 Grid View 控件,并使用了 XMLDataSource 而不是数据库(方便配置)进行页面显示。 

请参考以下代码片段。

<asp:XmlDataSource ID="xmlSource" runat="server" DataFile="~/XMLDataBase/MenFashion.xml">
</asp:XmlDataSource>

<asp:GridView ID="gvItemListing" runat="server" DataSourceID="xmlSource" 
AutoGenerateColumns = "false"
AllowPaging="true" PageSize="5" Width="100%" PagerSettings-Position="Bottom">

WatinWebScraper 应用程序代码片段

在这里,我将解释以下内容:

  1. 在应用程序中初始化 Watin 和 NUnit 
  2. 使用 Watin 进行网站导航 
  3. 使用 .NET 的正则表达式功能(RegEx 和 MatchCollection)从 HTML 页面源代码中获取相应数据
  4. 使用 NUnit 执行此应用程序

请参考以下对各部分的解释。

1) 在应用程序中初始化 Watin 和 NUnit

要使用 Watin 和 NUnit,请向 nunit.framework.dll、“Interop.SHDocVw.dll”和“WatiN.Core.dll”添加引用。
现在,在此项目中添加对“NUnit.Framework”和“WatiN.Core”的引用。

由于我们将使用 NUnit 来抓取此应用程序;它要求在创建类时包含“[TestFixture]”,并在该方法顶部使用“[Test]”和“[STAThread]”。

您可以通过访问 此网站 获取有关这些属性的更多详细信息。

2) 使用 Watin 进行 Web 抓取

// Create an instance of Internet Explorer browser 
IE ieInstance = new IE(webSitePath); 
// This will open Internet Explorer browser in maximized mode 
ieInstance.ShowWindow(WatiN.Core.Native.Windows.NativeMethods.WindowShowStyle.ShowMaximized); 

在执行 Web 抓取时,可以使用以下代码片段将 Watin 窗口隐藏起来。目前,这段代码被注释掉了。用户也可以取消注释此代码片段。

//ieInstance.Visible = false;

// This will wait for the browser to complete loading of the page 
ieInstance.WaitForComplete(); 

// This will store page source in categoryPageSource variable 
string categoryPageSource = ieInstance.Html;

3) 使用 .NET 的正则表达式功能(RegEx 和 MatchCollection)从 HTML 页面源代码中获取相应数据

我使用正则表达式来获取类别,并进行迭代逻辑来获取相应类别中的项目,以及移动到下一页,使用正则表达式来获取相应类别项目的所有页面。

请参考以下用于类别、项目抓取和页面导航的正则表达式。

类别正则表达式

<A\S.*?class=bold\s.*?href="(?<href>.*?)"></span>
代码解释

上述正则表达式将从 CategoryListing.aspx 页面获取所有类别 URL,并在递归循环中导航。

项目正则表达式

<P\s*id=.*?>ProductID:\s*<B>(?<ProductID>.*?)</B>.*?</P>\s*.*?<P\s*id=.*?>
ProductName:\s*<B>(?<ProductName>.*?)</B>.*?</P>\s*.*?<P\s*id=.*?>
ProductPrice:\s*<B>(?<ProductPrice>.*?)</B>.*?</P>
代码解释

上述正则表达式将获取给定页面中相应项目的 ProductID、产品名称和产品价格。

分页正则表达式

(?(?=<SPAN>.*?</SPAN>)<SPAN>(?<PageNumber>.*?)\s*</SPAN>|
<A\s*href="javascript.*?>(?<PageNumber>.*?)\s*</A>)
代码解释

上述正则表达式将从 ItemListing.aspx 页面获取相应的页面。

要在应用程序中使用此正则表达式,我使用了“System.Text.RegularExpression”命名空间中的“RegEx”类。RegEx 将使用不同的选项(如“RegexOptions.Compiled”、“RegexOptions.IgnoreCase”、“RegexOptions.IgnorePatternWhitespace”和“RegexOptions.CultureInvariant”)来编译相应的正则表达式模式。

请参考下面的代码片段。

// Regular expression for Category listing page 
private const string _categoryRegEx = <A\S.*?class=bold\s.*?href="(?<href>.*?)"></span>
Regex categoryMatches = new Regex(_categoryRegEx, RegexOptions.Compiled | 
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant);

要根据正则表达式获取记录,需要使用 MatchCollection 来获取针对相应 HTML 源生成的成功匹配列表(如 #2 所示,string categoryPageSource = ieInstance.Html;)。请参考下面的代码。

MatchCollection categoryMatchCollection = categoryMatches.Matches(categoryPageSource);

使用 for 循环获取单个匹配项的相应结果:请参考下面的代码。

foreach (Match categoryMatch in categoryMatchCollection)

如果正则表达式是基于组创建的,则使用 GroupCollection 方法获取相应结果的组。请参考下面的代码。

GroupCollection categoryGroup = categoryMatch.Groups;

GroupCollection 包含多个相关组。为了获取类别,我使用了“href”作为组。请参考下面的代码。

string itemListingURL = Convert.ToString(categoryGroup["href"].Value); 

现在,itemListingURL 变量将包含相应类别的 href。现在 Watin 将导航到该 URL,如下所示。
itemListingPath 变量包含相应类别的项目列表页面的完整路径。

ieInstance.GoTo(itemListingpath);

我使用了“WaitForComplete”方法来等待页面加载完成。请参考下面的代码。

ieInstance.WaitForComplete();

使用上述代码,应用程序将导航到项目列表页面。对于获取项目,需要执行类似的操作。

一旦获取了相应页面上的所有项目,并且要移动到下一页,Watin 提供了 Click 事件来执行对特定页面的单击。

Click 事件也可以根据其他不同标准执行。请参考下面。

Find.ByAlt Find.ByClass Find.ByDefault Find.ByElement Find.ByExistence OfRelatedElement Find.ByFor
Find.ById Find.ByIndex Find.ByLabelText Find.ByName Find.BySelector Find.BySrc
Find.ByStyle Find.ByText Find.ByTextInColumn Find.ByTitle Find.ByUrl Find.ByValue

您可以通过访问 此链接 了解有关上述所有标准的更多信息。

在本文中,我使用了“Find.ByText”来按文本查找链接,然后执行 click 事件。您也可以附加
上述标准中的正则表达式。

请参考下面的代码。

// Fetches the page number of the current page.
string linkText = Convert.ToString(pagingGroup[_pageNumber].Value); 

// Performs click event on the given link. For e.g if linkText contains "2" as a value 
// then Watin will perform click event on this second link.
ieInstance.Link(Find.ByText(linkText)).Click(); 
// Wait for the operation to complete
ieInstance.WaitForComplete(); 

// Store the result of the page in itemListingPageSource variable
itemListingPageSource = ieInstance.Html;

一旦抓取了网页上的相应项目,当前应用程序将使用 System.IO 命名空间中的 StreamWriter 将相应项目存储在“Output.txt”中。

现在打开“Output.txt”文件,您会发现它包含 MenWomen Children 类别中的所有项目。

4) 使用 NUnit 执行此应用程序

要执行 WatinWebScraper 应用程序,需要遵循以下步骤:

  1. 打开 NUnit 应用程序。
  2. 现在点击 File --> Open Project,然后导航到 Watin Web Scraper 应用程序的 DLL 文件(“WatinWebScraping.dll”)。请参考下面的图片。

Click to enlarge image

  1. 现在点击上图所示的“Run”按钮。您会发现应用程序将通过导航到类别来开始抓取演示 Web 应用程序,并且所有相应的项目都将存储在“Output.txt”文件中。
© . All rights reserved.