从代码进行外部网站搜索

时间:2011-06-28 18:52:42

标签: c# .net database search

我有一个带有姓氏,名字和邮政编码的csv文件。我想编写一个.NET程序来自动搜索www.canada411.com以获取该人的邮政编码和姓氏,并将所有结果记录在数据库中。

我不知道如何解决这个问题,但这些是我需要做的步骤:

  1. 阅读文件(我可以这样做)
  2. 使用文件中的信息搜索www.canada411.com(不知道如何操作)
  3. 确定页面的结果部分(不知道如何操作)
  4. 对于搜索的每个结果,阅读结果(不知道如何操作)并存储在数据库中(我可以做最后一点)。
  5. 你能指点我正确的方向吗?非常感谢提前

3 个答案:

答案 0 :(得分:2)

您所指的是屏幕抓取,这是一种将网页结果解析为有意义信息的高度不可靠的方法。

您最好找一个公开API的“邮政编码查询服务”,以便以编程方式检索此信息。这样,您的代码就不会因为提供商更改其网页设计而中断。

但是,要实现您的要求,您可以使用WebClient或构建HttpWebRequest。然后,您可以解析响应以查找您感兴趣的html区域。

使用HttpWebRequest的示例 - http://wiki.asp.net/page.aspx/285/httpwebrequest/
解析html的最佳工具 - http://htmlagilitypack.codeplex.com/

答案 1 :(得分:0)

有趣的问题。

1)获取人名的页面结果     各种各样的方法,但我建议WebClient使用URL http://www.canada411.ca/search/?stype=si&what=Smith%2C+John替换带有适当URL编码值的“Smith”和“John”字样

2)将结果返回加载到XML Reader对象

3)使用LINQ to XML或其他格式(如XPATH)使用class =“listing”收集所有Div元素

4)对于上面的每个元素3,使用LINQ to XML或XDocument从节点读取值并相应地存储到实例变量中。将需要一些解析逻辑。

5)将新记录插入数据库或更新现有记录

6)对所有列表节点重复

如果上述所有信息对您没有意义,那么恐怕没有一个简单的答案。最简单的方法是使用一些政府赞助的免费网络服务,如果你能找到一个并以一致的方式得到结果。

请记住,对页面布局,类名等的任何更改都会破坏您的代码。收集信息的方式非常不可靠,但可能适用于初始数据库负载等。

答案 2 :(得分:0)

我非常无聊,所以:

public class FourElevenLookup
{
    private const string URL = "http://www.canada411.ca/search/";
    private const string TYPE_PARAM = "?stype=si";
    private const string WHAT_PARAM = "&what=";
    private const string WHERE_PARAM = "&where=";

    public static List<SearchResult> GetResults(string lastName, string postalCode)
    {
        List<SearchResult> results = new List<SearchResult>();
        string fullUrl = URL + TYPE_PARAM + WHAT_PARAM + lastName +
            WHERE_PARAM + postalCode.Replace(" ", "+");
        string rawText = GetHtml(fullUrl);
        Regex getListings = new Regex("\\<\\!\\-\\- (listingDetail|listing) \\-\\-\\>(?<content>" + 
            "(.(?!(\\<\\!\\-\\- (\\/ listingDetail|listing) \\-\\-\\>)))*)", RegexOptions.Singleline);
        MatchCollection mc = getListings.Matches(rawText);
        List<string> rawListings = new List<string>();
        for (int i = 0; i < mc.Count; i++)
            rawListings.Add(mc[i].Groups["content"].Value);
        Regex parseListing = new Regex("\\<div class=\"c411ListingInfo\"\\>(.(?!a href=))*\\<a href\\=(.(?!\\>))*\">" + 
            "(?<name>[\\w- ]*)\\<\\/a\\>\\<br\\/\\>(.(?!span))*\\<span class\\=\"address\"\\>" + 
            "(?<address>(.(?!\\/span\\>))*)", RegexOptions.Singleline);            
        rawListings.ForEach(s =>
        {
            Match m = parseListing.Match(s);
            results.Add(new SearchResult()
            {
                Name = m.Groups["name"].Value,
                Address = m.Groups["address"].Value.Replace("<br/>", "")
            });
        });
        return results;
    }

    private static string GetHtml(string strURL)
    {
        string result;
        WebResponse objResponse;
        WebRequest objRequest = System.Net.HttpWebRequest.Create(strURL);
        objResponse = objRequest.GetResponse();
        using (StreamReader sr =
        new StreamReader(objResponse.GetResponseStream()))
        {
            result = sr.ReadToEnd();
            sr.Close();
        }
        return result;
    }
}

public struct SearchResult 
{
    public string Name { get; set; }
    public string Address { get; set; }
}