c# правило сканирования не работает на веб-сайте cnn - PullRequest
0 голосов
/ 21 марта 2020

Я новичок в C# ползать

Я пытался ползти новости CNN из (https://edition.cnn.com/)

Но мне не удалось получить текст заголовка.

цель выглядит как показано ниже html (извините, я не умею задавать вопросы, содержащие исходный код, newb ie TT)

<div class="cd__wrapper" data-analytics="_list-hierarchical-xs_article_">
<div class="cd__content">
<h3 class="cd__headline" data-analytics="_list-hierarchical-xs_article_">
<a href="/travel/article/cruise-ship-passengers-stranded-coronavirus/index.html">
<span class="cd__headline-text">At least 30 cruise ships are at sea. Here's what it's like on board.</span><span class="cd__headline-icon cnn-icon"></span></a></h3></div></div>

Первый я попытался сканировать все коды html, а затем преобразовать в строку (моя цель - получить текст заголовка со ссылкой href для сканирования дочерних страниц)

с кодами ниже c#

public async void GetCnnAsync()
    {
        var url = "https://edition.cnn.com/";

        var httpClient = new HttpClient();
        var html = await httpClient.GetStringAsync(url);

        var htmlDocument = new Hp.HtmlDocument();
        htmlDocument.LoadHtml(html);

        var headLineHtmlList = htmlDocument.DocumentNode.Descendants("div")
            .Where(node => node.GetAttributeValue("class", "")
            .Contains("cd__headline")).ToList();


        Console.ReadLine();
    }

но это не сработало, просто получил null headLineHtmlList. Я не знаю, почему мне не удалось получить результат. потому что chrome Источник страницы инспектора имеет эти элементы

С другой стороны, когда я пытался сделать это на сайте stackoverflow. Мне удалось получить список вопросов с кодами ниже

public async void GetHtmlAsync()
    {
        var url = "https://stackoverflow.com/questions";

        var httpClient = new HttpClient();
        var html = await httpClient.GetStringAsync(url);

        var htmlDocument = new Hp.HtmlDocument();
        htmlDocument.LoadHtml(html);

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

        var questionList = questionsHtml[0].Descendants("div")
            .Where(node => node.GetAttributeValue("id", "")
            .Contains("question-summary")).ToList();
    }

Мне удалось получить список вопросов.

Теперь я действительно очень хочу получить результат с сайта CNN, пожалуйста, помогите мне Спасибо заранее

добавить больше тестовых кодов

создать элемент управления WebBrowser
, затем перейти, затем получить обратный вызов WebBrowser_DocumentCompleted

, но я не получил результат снова

, поэтому Я попробовал это снова с documentCompleted, но я не получил его

        WebBrowser webBrowser;
    Control parent;
    WebNewsCallback newsCallback;

    public WebNewsCrawler(Control parent, WebNewsCallback newsCallback) {
        this.parent = parent;
        this.newsCallback = newsCallback;
        if (webBrowser == null) {
            webBrowser = new WebBrowser {
                Visible = false,
                ScriptErrorsSuppressed = true
            };
        }
        parent.Controls.Add(webBrowser);
        webBrowser.DocumentCompleted += WebBrowser_DocumentCompleted;
    }

    public void doWork(string address) {
        webBrowser.Navigate(address);
    }

    int count = 0;

    private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
        if (webBrowser.ReadyState != WebBrowserReadyState.Complete) return;
        newsCallback(webBrowser.DocumentStream);
        GetCnn(webBrowser.DocumentStream);
        Console.WriteLine(count.ToString());
        count++;
    }

    public void GetCnn(Stream stream) {
        var doc = new Hp.HtmlDocument();
        doc.Load(stream, Encoding.UTF8);

        var nodes = doc.DocumentNode.SelectNodes("/html/body/div[7]/section[2]/div[2]/div/div[1]/ul/li[4]/article/div/div/h3/a/span[1]");
        if(nodes != null) {
            Console.WriteLine("xpath nodes not null");
        }

        var headLineHtmlList = doc.DocumentNode.Descendants("h3").ToList();                
        if (headLineHtmlList != null) {
            Console.WriteLine("headLineCount " +headLineHtmlList.Count.ToString());
        }
    }

headLineCount равен 0, а результат xPath равен нулю (xpath или xpath полный путь тот же результат)

1 Ответ

0 голосов
/ 09 апреля 2020

Вы уверены, что используемый вами селектор правильный? Вы сказали:

var headLineHtmlList = htmlDocument.DocumentNode.Descendants("div") .Where(node => node.GetAttributeValue("class", "") .Contains("cd__headline")).ToList();

Разве это не говорит: «Дайте мне всех потомков с тегом <div> и CSS класс cd__headline»?

Но вы не ищете div с классом cd__headline. Вы ищете <a> теги, встречающиеся внутри <h3> тегов, которые имеют класс CSS cd__headline.

Я могу ошибаться, но если я прав, это будет легко исправить! Удачи.

...