簡體   English   中英

使用 HtmlAgilityPack 從 C# 中的網站抓取特定數據

[英]Scraping specific pieces of data from website in C# using HtmlAgilityPack

我很想使用 HtmlAgilityPack 為某個嵌套的 div class 抓取 web 頁面,該頁面包含帶有我要提取的數據的 span 標簽

我想要的元素文本的完整 XPath :

/html/body/div[2]/div/div[1]/div/table/tbody/tr/td/span

我的代碼:

  static void Main(string[] args)
        {
            HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();
            HtmlAgilityPack.HtmlDocument doc = web.Load("http://watchout4snakes.com/wo4snakes/Random/RandomParagraph");

            var paragraph = doc.DocumentNode.SelectNodes("//div[@class='mainBody']//div[@class='content']//div[@class='resultContainer']" +
                "//div[@class='resultBox']//table[@class='paragraphResult']").ToList();

            foreach (var item in paragraph)
            {
                Console.WriteLine(item.InnerText);
            }
        }

我已經嘗試將完整的 XPath 放入doc.DocumentNode.SelectNodes()以及 Xpath 中,即//*[@id='result']我的問題是它要么什么都不返回,要么我收到一條錯誤消息Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source') Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source') Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'source')doc.DocumentNode.SelectNodes()行上。

問題來源是頁面加載后由JS腳本通過AJAX加載段落。 如果您在瀏覽器中打開開發工具/網絡,您可以看到。

加載的頁面部分如下所示

<table class="paragraphResult">
    <tr>
        <td>
            <span id="result"></span>
        </td>
    </tr>
</table>

里面什么都沒有。

加載后,頁面將 AJAX POST 請求發送到相同的 URL 並獲取帶有參數的純字符串

Subject1: "",
Subject2: ""

以及它在 URL 編碼格式中的外觀

Subject1=&Subject2=

要執行模擬表單行為,您可以手動發送 POST 請求。 HtmlAgilityPack在這里沒有用,因為接收到的數據只是一個純字符串。

class Program
{
    private static readonly HttpClient client = new HttpClient();

    static async Task Main(string[] args)
    {
        Console.Write("Proper Noun 1: ");
        string subject1 = Console.ReadLine();
        Console.Write("Proper Noun 2: ");
        string subject2 = Console.ReadLine();
        Dictionary<string, string> parameters = new Dictionary<string, string>()
        {
            { "Subject1", subject1 },
            { "Subject2", subject2 }
        };
        try
        {
            string result = await PostHTTPRequestAsync("http://watchout4snakes.com/wo4snakes/Random/RandomParagraph", parameters);
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

    private static async Task<string> PostHTTPRequestAsync(string url, Dictionary<string, string> data)
    {
        using (HttpContent formContent = new FormUrlEncodedContent(data))
        using (HttpResponseMessage response = await client.PostAsync(url, formContent).ConfigureAwait(false))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
    }
}

控制台 output

Proper Noun 1: test
Proper Noun 2: StackOverflow
When will the bass garage StackOverflow? A digest sighs test below the objective card. Why won't test finish behind a girlfriend? A heating science approaches test.

效果很好。 您只需在瀏覽器中正確分析 HTTP 流量即可。 HttpClient也是與 web 交互的強大工具。

暫無
暫無

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

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