簡體   English   中英

循環遍歷 HtmlNodes 並收集數據每次都會給我相同的結果

[英]Looping through HtmlNodes and collecting data gives me the same result every time

我有一個async方法,它調用映射器將 HTML 字符串轉換為IEnumerable

public async Task<IEnumerable<MovieRatingScrape>> GetMovieRatingsAsync(string username, int page)
{
    var response = await _httpClient.GetAsync($"/betyg/{username}?p={page}");
    response.EnsureSuccessStatusCode();
    var html = await response.Content.ReadAsStringAsync();
    return new MovieRatingsHtmlMapper().Map(html);
}

...

public class MovieRatingsHtmlMapper : HtmlMapperBase<IEnumerable<MovieRatingScrape>>
{
    // In reality, this method belongs to base class with signature T Map(string html)
    public IEnumerable<MovieRatingScrape> Map(string html)
    {
        var htmlDocument = new HtmlDocument();
        htmlDocument.LoadHtml(html);
        return Map(htmlDocument);
    }

    public override IEnumerable<MovieRatingScrape> Map(HtmlDocument item)
    {
        var movieRatings = new List<MovieRatingScrape>();
        var nodes = item.DocumentNode.SelectNodes("//table[@class='list']/tr");

        foreach (var node in nodes)
        {
            var title = node.SelectSingleNode("//td[1]/a")?.InnerText;

            movieRatings.Add(new MovieRatingScrape
            {
                Date = DateTime.Parse(node.SelectSingleNode("//td[2]")?.InnerText),
                Slug = node.SelectSingleNode("//td[1]/a[starts-with(@href, '/film/')]")?
                    .GetAttributeValue("href", null)?
                    .Replace("/film/", string.Empty),
                SwedishTitle = title,
                Rating = node.SelectNodes($"//td[3]/i[{XPathHasClass("fa-star")}]").Count
            });
        }

        return movieRatings;
    }
}

結果列表movieRatings包含相同object的副本,但是當我查看HTML以及調試和查看HtmlNode node時,它們與預期的不同。

要么我對一些非常明顯的事情視而不見,要么我遇到了一些我沒有掌握的async問題。 有任何想法嗎? 我應該從這個調用中得到 50 個獨特的對象,現在我只得到前 50 次。

提前謝謝你,維克多。

編輯:添加一些屏幕截圖以顯示我的困境。 查看foreach循環的第 1 項和第 2 項的 locals InnerHtml ( node ) 和標題。

編輯 2:設法在 .NET 上重現小提琴: https://dotnetfiddle.net/A2I4CQ

在此處輸入圖像描述 在此處輸入圖像描述

您需要使用.//而不是//

這是固定的小提琴: https://dotnetfiddle.net/dZkSRN


//將搜索文檔中的任何位置

.//將搜索當前節點中的任何位置

我不太確定如何描述這個,但你的問題就在這里(我認為)

//table[@class='list']/tr"

特別是//

我在尋找跨度時遇到了同樣的事情。 我不得不使用類似的東西

    var nodes = htmlDoc.DocumentNode.SelectNodes("//li[@class='itemRow productItemWrapper']");
            foreach(HtmlNode node in nodes)
            {
                var nodeDoc = new HtmlDocument();
                nodeDoc.LoadHtml(node.InnerHtml);

string name = nodeDoc.DocumentNode.SelectSingleNode("//span[@class='productDetailTitle']").InnerText;
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM