首页 > 解决方案 > 从网页获取数据到 C# 应用程序

问题描述

我正在尝试在 C# 中创建一个桌面应用程序,该应用程序将从网站检索数据。简而言之,这是一个应用程序,我将使用它来为我当地联赛的梦幻足球(足球)比赛创建统计数据。我想使用的所有数据都可以在线免费获得,但没有可用于检索数据的 API。

我尝试的第一件事是使用WebClientand获取网站的 HTML 代码DownloadString

WebClient client = new WebClient();
string priceChangeString = client.DownloadString(url);

然而,事实证明数据不在 HTML 字符串中。

如果我在 Chrome 中使用开发人员工具,我可以检查“元素”下的页面。在这里,我看到了我想要的数据:

Chrome 开发者工具截图

我试图通过使用“复制为 XPath”和 HtmlAgilityPack 来获取这些值,但我无法让它在我的代码中工作:

using HtmlAgilityPack;

string url = "https://fantasy.eliteserien.no/a/statistics/cost_change_start";

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);

string userscore = doc.DocumentNode.SelectNodes("//*[@id=\"main\"]/div[3]/div/div[2]/div[1]/div[2]/div[1]/div/div[2]/a/span[1]")[0].InnerText;

我尝试了此代码的几种变体,但它们都返回NullReferenceExceptions

未处理的异常:System.NullReferenceException:对象引用未设置为对象的实例。

在 C:\Users\my_username\source\repos\FantasyTest\FantasyTest\Program.cs:line 27 中的 FantasyTest.Program.Main(String[] args)

当我尝试使用 HtmlAgilityPack 和 XPath 时,有人看到我做错了什么吗?我还有其他方法可以解决这个问题吗?

可以在此处找到此示例中的网页

标签: c#

解决方案


我使用了一个列表来存储所有信息,然后通过该列表进行搜索,例如<span>,在所有<spans>的应用程序中进行搜索class="card-list"

var url = "https://fantasy.eliteserien.no/a/statistics/cost_change_start";
var httpClient = new HttpClient();
var html = await httpClient.GetStringAsync(url);
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html);
//This is the part of the code that takes information from the website
//Note that this part matches your screenshot, in the HTML code
//You can use that there is a table with class="ism-table ism-table--el"
//This piece of code target that specific table
var ProductsHtml = htmlDocument.DocumentNode.Descendants("table")
    .Where(node => node.GetAttributeValue("class", "")
    .Equals("ism-table ism-table--el")).ToList(); ;
    try{
    var ProductListItems = ProductsHtml[0].Descendants("tr")
    foreach (var ProductListItem in ProductListItems)
    {
        //This targets whats inside the table
        Console.WriteLine("Id: " +
        ProductListItem.Descendants("<HEADER>")
        .Where(node => node.GetAttributeValue("<CLASS>", "")
        .Equals("<CLASS=>")).FirstOrDefault().InnerText
    );
}

在您的情况下,我认为您需要正则表达式来匹配数字。这个网站有<td>number</td>格式的数字。我们需要的是<td class="mNOK">number</td>. 所以你需要使用正则表达式来匹配所有的数字。为此,我们这样做:

//Regex Match numbers in <td>
Console.WriteLine("numbers: " +
Regex.Match(ProductListItem.Descendants("td").FirstOrDefault().InnerText
, @[0-9]")
);

请注意,您需要更改<URL><HEADER>和。<CLASS><CLASS=>

<URL>:您要从中获取信息的站点, <HEADER>:您要针对阅读 HTML 代码中的哪个标头。例如 "span, div, li, ul", <CLASS>: 在该标题中,您要查找什么。Example "id, name", <CLASS=>:<CLASS>需要等于什么,才能读取内文


推荐阅读