c# - 在 Xamarin 中使用 HtmlAgilityPack 等待 AJAX

标签 c# ajax xamarin html-agility-pack

我有一个问题似乎以前有人问过,但有点不同。我正在尝试从 this website 中抓取数据但问题是它似乎加载了 AJAX。因此,我的应用程序无法在我要查找的 HTML 中找到 ID 和类。

您可以通过检查元素或查看源代码来重现此内容。在查看源代码时,我看到的东西比检查元素时少得多。

我想我可以找到包含 AJAX 的文件来加载此 html,方法是按 F12,转到网络选项卡并选择 XHR,但我无法找到它。

My question is: how do I retrieve this data or find out what file is used to collect the data?

我的代码示例(我找不到 Timetable_toolbar_elementSelect_popup0):

private async Task GetHtmlDocument(string url)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            //request.Credentials = new LoginCredentials().Credentials;

            try
            {
                WebResponse myResponse = await request.GetResponseAsync();
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.OptionFixNestedTags = true;
                htmlDoc.Load(myResponse.GetResponseStream());
                var test = htmlDoc.GetElementbyId("Timetable_toolbar_elementSelect_popup0");
            }
            catch (Exception e)
            {
            }
        }

最佳答案

我本来打算把它留作评论。但是它变得太大而且格式太糟糕。所以我们开始吧。

首先。该站点使用通过 ajax 命令调用的 javascript 动态更新。

如果您可以打开一个 session 并存储包含 SESSIONID 和现在“加密”的学校名称的 cookie,那么您可以这样调用 ajax 命令。

    https://roosters.windesheim.nl/ajaxCommand=getWeeklyTimetable&elementType=1&elementId=13090&date=20171126&formatId=7&departmentId=0&filterId=-2

然而,这确实需要您知道什么是 elementType 和什么是 elementId。

在这种情况下,当 elementId 等于 1GLD 时,它指的是 Klas。当 formatID(7) 等于“Beknopt”时,它指的是 Roosterformaat。您必须弄清楚其余变量的作用。更重要的是,如果您成功地能够向服务器发出有效的 ajax 命令,那么您将不会收到 html 作为响应,您将收到 JSON 格式的数据。

做你想做的最简单的方法是把所有的类都放在一个单独的file 中。 .并将其用作引用点。其他选项也是如此。

然后使用像phantomjs.org 这样的 headless 浏览器与 Selenium .通过这种方式,您可以找到并单击要抓取的类。将 html 加载到 HtmlAgilityPack.HtmlDocument 中,然后执行您需要执行的操作。 Selenium/PhantomJS 直到跟踪你的 cookie。 这种方法速度较慢 - 但更容易做到。

编辑从网络请求中存储 cookies - 简单的方法。

我不喜欢这个话题。但是OP问。如果有人有更好的方法,请编辑。

CookieContainer cookies = new CookieContainer();
try
{
    string webAddr = "https://roosters.windesheim.nl/WebUntis/";

    var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
    httpWebRequest.ContentType = "application/json; charset=utf-8";
    httpWebRequest.Method = "POST";
    httpWebRequest.CookieContainer = cookies;
          
    httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    httpWebRequest.Headers.Add("X-Requested-With", "XMLHttpRequest");
    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
    {
        string json = "ajaxCommand=getWeeklyTimetable&elementType=1&elementId=13092&date=20171126&formatId=7&departmentId=0&filterId=-2";

        streamWriter.Write(json);
        streamWriter.Flush();
    }
            

    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
        cookies.Add(httpWebRequest.CookieContainer.GetCookies(httpWebRequest.RequestUri));
        //cookies.Add(httpResponse.Cookies);
        var responseText = streamReader.ReadToEnd();
        doc.LoadHtml(responseText);
        foreach(Cookie c in httpResponse.Cookies)
        {
            Console.WriteLine(c.ToString());
        } 
    }
}
catch (WebException ex)
{
    Console.WriteLine(ex.Message);
}
    Console.WriteLine(doc.DocumentNode.InnerHtml);

    Console.ReadKey();

关于c# - 在 Xamarin 中使用 HtmlAgilityPack 等待 AJAX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47491022/

相关文章:

c# - 当页面向后导航到带有 MapControl 的页面时,UAP 应用程序崩溃

javascript - 尝试循环访问对象中名为 strIngredients 1-15 的项目

c# - Polly 在 X 次重试后继续

ios - Xamarin.iOS & XCode 8.3 : how to download provisioning profiles?

ios - Xamarin UI 测试 : Calabash not linked

c# - Delphi 记录转换为 C# 结构并写入套接字

c# - 没有定义故障契约时,如何访问 SOAP 故障中的 <detail> 部分?

c# - 如何从 removeall 获取 "success"的指示

java - 如何在 JSONP 请求中使用 @RequestBody?

jquery - Ajax Jquery PUT 请求不起作用