使用HtmlAgilityPack进行Web爬网Java站点

时间:2019-01-31 04:27:29

标签: c# .net web-scraping html-agility-pack

让我首先说我不是网络抓取专家。我可以在大多数平台上进行基础操作,但是仅此而已。

我正在尝试为Web应用程序创建基础,该应用程序可以通过生成其他数据,指标以及创建用于自我测试的新工具来帮助用户加强其语言学习。 Duolingo网站没有提供任何类型的API,因此我现在的下一个想法是 只是删除https://www.duome.eu/。我写了一个快速的小刮板,但没有意识到该站点是Java。在以下示例中,我希望从Words标签中收集所有包含锚点的单词:

using System;
using HtmlAgilityPack;
using System.Net.Http;
using System.Text.RegularExpressions;

namespace DuolingoUpdate
{
    class Program
    {
        static void Main(string[] args)
        {
            string userName = "Podus";
            UpdateDuolingoUser(userName);
            Console.ReadLine();
        }

        private static async void UpdateDuolingoUser(string userName)
        {
            string url = "https://www.duome.eu/" + userName + "/progress/";

            // Create the http client connection
            HttpClient httpClient = new HttpClient();
            var html = await httpClient.GetStringAsync(url);

            // Store the html client data in an object
            HtmlDocument htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(html);

            //var words = htmlDocument.DocumentNode.Descendants("div")
            //    .Where(node => node.GetAttributeValue("id", "")
            //    .Equals("words")).ToList();

            //var wordList = words[0].Descendants("a")
            //    .Where(node => node.GetAttributeValue("class", "")
            //    .Contains("wA")).ToList();

            Console.WriteLine(html);
        }
    }
}

以上代码的html对象包含:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="google" value="notranslate">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Duolingo · Podus @ duome.eu</title>
<link rel="stylesheet" href="/style.css?1548418871" />
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        if("".length==0){
            var visitortime = new Date();
            var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
            //localStorage.tz = visitortimezone;
            //timezone = Date.parse(localStorage.tz);
            //timezone = localStorage.tz;
            //console.log(timezone);
            $.ajax({
                type: "GET",
                url: "/tz.php",
                data: 'time='+ visitortimezone,
                success: function(){
                    location.reload();
                }
            });
        }
    });
</script>

</head>
<body>
<noscript>Click <a href="https://duome.eu//Podus/progress/">here</a> to adjsut XP charts to your local timezone. </noscript>
<!-- Yandex.Metrika counter --> <script type="text/javascript" > (function (d, w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter47765476 = new Ya.Metrika({ id:47765476, clickmap:true, trackLinks:true, accurateTrackBounce:true }); } catch(e) { } }); var n = d.getElementsByTagName("script")[0], s = d.createElement("script"), f = function () { n.parentNode.insertBefore(s, n); }; s.type = "text/javascript"; s.async = true; s.src = "https://mc.yandex.ru/metrika/watch.js"; if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); } })(document, window, "yandex_metrika_callbacks"); </script> <noscript><div><img src="https://mc.yandex.ru/watch/47765476" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter -->
</body>
</html>

但是,如果您转到实际的URL https://www.duome.eu/Podus/progress/,则该站点包含大量脚本。因此,在检查时,第一个问题是我没有获得在浏览器中看到的html。第二个问题是,如果您查看源代码,它与inspect中的内容完全不同,而且我在源代码中也看不到任何东西会导致我将数据与div id="words"隔离开来。

鉴于我对Java构建的网页缺乏了解,我该怎么做,或者甚至有可能?

1 个答案:

答案 0 :(得分:1)

您可以通过https://www.duolingo.com/users/<username>

访问JSON格式的Dualingo配置文件数据

例如https://www.duolingo.com/users/Podus

与尝试手动抓取duome个人资料页面相比,这应该容易得多。