1

我正在使用 Yahoo Placefinder 服务来查找我在 csv 文件中的地址列表的一些纬度/经度位置。

我正在使用以下代码:

String reqURL = "http://where.yahooapis.com/geocode?location=" + HttpUtility.UrlEncode(location) + "&appid=KGe6P34c";

XmlDocument xml = new XmlDocument();
xml.Load(reqURL);
XPathNavigator nav = xml.CreateNavigator();
// process xml here...

我刚刚发现了一个非常顽固的错误,我认为(错误地)好几天是由于雅虎禁止我的进一步请求。

它适用于这个 URL:

http://where.yahooapis.com/geocode?location=31+Front+Street%2c+Sedgefield%2c+Stockton%06on-Tees%2c+England%2c+TS21+3AT&appid=KGe6P34c

我的浏览器抱怨该网址的解析错误。我的 c# 程序说它有 500 错误。

这里的位置字符串来自这个地址:

Agape Business Consortium Ltd.,michael.cutbill@agapesolutions.co.uk,Michael A Cutbill,Director,,,9 Jenner Drive,Victoria Gardens,,Stockton-on-Tee,,TS19 8RE,,England,85111,Hospitals,www.agapesolutions.co.uk

我认为错误来自 中的第一个连字符Stockton-on-Tee,但我无法解释为什么会这样。如果我将此连字符替换为“正常”连字符,则查询成功。

此错误是由于我的端故障(HttpUtility.UrlEncode功能不正确?)还是雅虎端的故障?

尽管我可以看到导致此问题的原因,但我不明白为什么。有人可以解释一下吗?

编辑:

我的进一步调查表明,这个连字符被编码为“%06”的字符是 ascii 控制字符“Acknowledge”、“ACK”。我不知道为什么这个角色会出现在这里。似乎不同的地方Stockton-on-Tee以不同的方式呈现 - 它似乎在文本编辑器中正常打开,但当它出现在 Visual Studio 中时,在被编码之前,它是Stocktonon-Tees. 请注意,当我在 Firefox 中将前一个复制到此文本框中时,hypen 呈现为一个奇怪的方形框字符,但在随后的编辑中,SO 软件似乎已经对字符进行了处理。

我在下面包含了我用来解析 csv 文件的函数和持有者类 - 正如你所看到的,我没有做任何可能引入意外字符的奇怪操作。危险人物出现在“城镇”字段中。

public List<PaidBusiness> parseCSV(string path)
{
    List<PaidBusiness> parsedBusiness = new List<PaidBusiness>();
    List<string> parsedBusinessNames = new List<string>();

    try
    {
        using (StreamReader readFile = new StreamReader(path))
        {
            string line;
            string[] row;

            bool first = true;
            while ((line = readFile.ReadLine()) != null)
            {
                if (first)
                    first = false;
                else
                {
                    row = line.Split(',');
                    PaidBusiness business = new PaidBusiness(row);
                    if (!business.bad) // no problems with the formatting of the business (no missing fields, etc)
                    {
                        if (!parsedBusinessNames.Contains(business.CompanyName))
                        {
                            parsedBusinessNames.Add(business.CompanyName);
                            parsedBusiness.Add(business);
                        }
                    }
                }
            }
        }
    }
    catch (Exception e)
    {  }

    return parsedBusiness;
}

public class PaidBusiness
{
    public String CompanyName, EmailAddress, ContactFullName, Address, Address2, Address3, Town, County, Postcode, Region, Country, BusinessCategory, WebAddress;
    public String latitude, longitude;
    public bool bad;


    public static int noCategoryCount = 0;
    public static int badCount = 0;

    public PaidBusiness(String[] parts)
    {
        bad = false;

        for (int i = 0; i < parts.Length; i++) 
        {
            parts[i] = parts[i].Replace("pithawala", ",");
            parts[i] = parts[i].Replace("''", "'");
        }

        CompanyName = parts[0].Trim();
        EmailAddress = parts[1].Trim();
        ContactFullName = parts[2].Trim();
        Address = parts[6].Trim();
        Address2 = parts[7].Trim();
        Address3 = parts[8].Trim();
        Town = parts[9].Trim();
        County = parts[10].Trim();
        Postcode = parts[11].Trim();
        Region = parts[12].Trim();
        Country = parts[13].Trim();
        BusinessCategory = parts[15].Trim();
        WebAddress = parts[16].Trim();

        // data testing
        if (CompanyName == "")
            bad = true;
        if (EmailAddress == "")
            bad = true;
        if (Postcode == "")
            bad = true;
        if (Country == "")
            bad = true;
        if (BusinessCategory == "")
            bad = true;

        if (Address.ToLower().StartsWith("po box"))
            bad = true;

        // its ok if there is no contact name.
        if (ContactFullName == "")
            ContactFullName = CompanyName;

        //problem if there is no business category.
        if (BusinessCategory == "")
            noCategoryCount++;

        if (bad)
            badCount++;

    }       
}
4

1 回答 1

2

欢迎来到真实世界的数据。问题可能出在 CSV 文件中。要验证,请阅读该行并检查每个字符:

foreach (char c in line)
{
    Console.WriteLine("{0}, {1}", c, (int)c);
}

“正常”连字符将为您提供 45 的值。

另一个问题可能是您正在使用错误的编码读取文件。可能是该文件被编码为 UTF8 并且您正在使用默认编码读取它。您可以尝试在打开文件时指定 UTF8:

using (StreamReader readFile = new StreamReader(path, Encoding.UTF8))

这样做,然后再次输出该行上的每个字符(如上),看看你得到的连字符是什么字符。

于 2011-09-29T15:16:32.550 回答