如何从网站发布和检索数据



我正在使用一个Windows窗体应用程序。我有一个名为"tbPhoneNumber"的文本框,其中包含一个电话号码。

我想上网站http://canada411.com并在我的文本框中输入数字,输入网站文本框ID:"c411PeopleReverseWhat",然后以某种方式点击"Find"(这是属于类"c411ButtonMig"的输入)。

之后,我想检索以下HTML部分的星号之间的内容:

<div id="contact" class="vcard">
        <span><h1 class="fn c411ListedName">**Full Name**</h1></span>
        <span class="c411Phone">**(###)-###-####**</span>
        <span class="c411Address">**Address**</span>
        <span class="adr">
            <span class="locality">**City**</span>
            <span class="region">**Province**</span>
            <span class="postal-code">**L#L#L#**</span>
        </span>

因此,基本上我尝试将数据发送到输入框中,单击输入按钮并将检索到的值存储到变量中。我想做这件事看起来毫无意义,所以我需要做一些类似HTTPWebRequest的事情?还是使用WebBrowser对象?我只是不想让用户看到应用程序正在网站上运行。

我做了大量的网站抓取,我会向你展示我是如何做到的。如果我太具体了,可以跳过,但这是一个常见的主题,应该具体化。

URL简化

我为此使用的库是htmlagilitypack(它是一个dll,创建一个新项目并添加对它的引用)。首先要检查的是,我们是否必须采取任何特殊步骤才能使用电话号码进入页面。我找了约翰·史密斯,找到了不少。我输入了其中的2个结果,并注意到url格式非常简单。这些结果是。。

http://www.canada411.ca/res/7056736767/John-Smith/138223109.html

http://www.canada411.ca/res/7052355273/John-Smith/172439951.html

我测试了一下是否可以从url中删除一些我不知道的值,然后留下电话号码。结果是我可以。。。

http://www.canada411.ca/search/re/1/7056736767/-

http://www.canada411.ca/search/re/1/7052355273/-

你可以通过url看到url和我们的电话号码中有一些静态区域。由此,我们可以为url构造一个字符串。

Dim phoneNumber as string = "7056736767" 'this could be TextBox1.Text or whatever
Dim URL as string = "http://www.canada411.ca/search/re/1/" + phoneNumber +"/-"

使用XPath提取值

现在我们已经拨入了页面,让我们检查一下您在上面提供的html。您需要页面中的6个值,因此我们现在将创建它们。。。

Dim FullName As String
Dim Phone As String
Dim Address As String
Dim Locality As String
Dim Region As String
Dim PostalCode As String  

如上所述,我们将使用使用Xpath的htmlagilitypack。最酷的是,一旦我们能在html中找到一些唯一的标识符,我们就可以使用Xpath来找到我们的值。我知道这可能令人困惑,但它会变得更清楚。

您需要的所有值都在具有类名的标记中。让我们使用Xpath中的类名来查找它们。

Dim FullNameXPath As String = "//*[@class='fn c411ListedName']"
Dim PhoneXPath  As String = "//*[@class='c411Phone']"
Dim AddressXPath  As String = "//*[@class='c411Address']"
Dim LocalityXPath  As String = "//*[@class='locality']"
Dim RegionXPath  As String = "//*[@class='region']"
Dim PostalCodeXPath  As String = "//*[@class='postal-code']"

从本质上讲,我们看到的是一个字符串,它将通知htmlagilitypack要查找什么。在我们的例子中,文本包含在我们命名的类中。XPath有很多内容,可能需要一段时间来解释所有内容。。。若您使用Google Chrome并在页面上突出显示某个值,则可以右键单击inspect元素。在下面显示的代码中,您可以右键单击该值并将其复制到XPath!!!非常有用。

基本HTMLAgilityPack模板

现在,剩下的就是连接到页面并填充这些变量。

Dim Web As New HtmlAgilityPack.HtmlWeb
Dim Doc As New HtmlAgilityPack.HtmlDocument
Doc = Web.Load(URL)
For Each nameResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(FullNameXPath)
     Msgbox(nameResult.InnerText)        
Next

在上面的例子中,我们创建了一个名为Web的HtmlWeb对象。这是我们项目的实际爬虫。然后,我们定义一个HtmlDocument,它将由我们转换和可搜索的页面源组成。所有这些都是在幕后完成的。然后,我们发送Web来获取页面源,并将其分配给我们创建的Doc对象。Doc是可重用的,谢天谢地,它只需要我们连接到页面一次。

for循环在文档中查找与FullNameXPath匹配的任何节点,FullNameXPath之前被定义为查找名称的XPath值。当找到一个节点时,它被分配给nameResult变量,在循环中我们调用一个消息框来显示节点的内部文本。

所以当我们把它们放在一起

完整的工作规范(截至2013年2月17日)

Dim phoneNumber As String = "7056736767" 'this could be TextBox1.Text or whatever
Dim URL As String = "http://www.canada411.ca/search/re/1/" + phoneNumber + "/-"
Dim FullName As String
Dim Phone As String
Dim Address As String
Dim Locality As String
Dim Region As String
Dim PostalCode As String
Dim FullNameXPath As String = "//*[@class='fn c411ListedName']"
Dim PhoneXPath As String = "//*[@class='c411Phone']"
Dim AddressXPath As String = "//*[@class='c411Address']"
Dim LocalityXPath As String = "//*[@class='locality']"
Dim RegionXPath As String = "//*[@class='region']"
Dim PostalCodeXPath As String = "//*[@class='postal-code']"
Dim Web As New HtmlAgilityPack.HtmlWeb
Dim Doc As New HtmlAgilityPack.HtmlDocument
Doc = Web.Load(URL)
For Each nameResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(FullNameXPath)
    FullName = nameResult.InnerText
    MsgBox(FullName)
Next
For Each PhoneResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(PhoneXPath)
    Phone = PhoneResult.InnerText
    MsgBox(Phone)
Next
For Each ADDRResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(AddressXPath)
    Address = ADDRResult.InnerText
    MsgBox(Address)
Next
For Each LocalResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(LocalityXPath)
    Locality = LocalResult.InnerText
    MsgBox(Locality)
Next
For Each RegionResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(RegionXPath)
    Region = RegionResult.InnerText
    MsgBox(Region)
Next
For Each postalCodeResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(PostalCodeXPath)
    PostalCode = postalCodeResult.InnerText
    MsgBox(PostalCode)
Next

是的,这是可能的,我已经使用selenium框架完成了这项工作,该框架旨在测试自动化。然而,它为您提供了实现这一点的工具。

在此处下载.net:http://docs.seleniumhq.org/download/

相关内容

  • 没有找到相关文章

最新更新