Попытка получить список песен на сайте не работает

Я попытался использовать phantomjs, cheerio в узле и элемент управления webBrowser на C #, чтобы получить свой список песен, я могу успешно получить html, но без списка песен я не могу понять, почему я не могу его получить ...

Единственный способ, которым я могу это сделать, - это скопировать html с помощью инструмента разработчика и проанализировать его с помощью JQuery.

Вот мой код в WinForm:

  private void Form1_Load(object sender, EventArgs e)
    {
        webBrowser1.Navigate("http://grooveshark.com/#!/shinningstar1001/collection");
        webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
    }

    void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        File.WriteAllText("D://test.txt", webBrowser1.DocumentText);
    }

В Cheerio:

var cheerio = require('cheerio');
var request = require('request');

var url = 'http://grooveshark.com/#!/shinningstar1001/collection';

request({
    url: url,
    headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
}, function (err, resp, body) {
    $ = cheerio.load(body);
    console.log(body);        
})

Я думаю, это потому, что я не могу получить полный документ после загрузки ajax?

Но почему WebBrowser Control тоже не работает? Я вижу, что в элемент управления загружено полное содержимое. Любой совет буду очень признателен.

Я пробовал решение @Murray Foxcroft, все еще не могу получить именно тот html, который мне нужен: введите описание изображения здесь

Дополнительный вопрос

С помощью решения @Murray Foxcroft я могу получить 8% содержимого списка, но почему я не могу получить полный список песен, который отображается на странице? Например, я могу получить песню «Освободи меня», которая находится примерно на 40-м месте в списке, но не могу получить «This Love», которая находится примерно на 70-м месте в списке. (Две песни точно есть на сайте)

        if (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
            return;
        if (richTextBox1.Text.Length > 0) return;
        var songList = webBrowser1.Document.GetElementById("profile-grid");

        //try to get "This Love" that never step into the code:
        if (songList != null && songList.InnerHtml.Contains("This Love")){...}

        //"Set Me Free" is OK:
        if (songList != null && songList.InnerHtml.Contains("Set Me Free"))
        {
            richTextBox1.Text = songList.OuterHtml;                
        }        

person Sing    schedule 30.12.2014    source источник


Ответы (1)


В примере WebBrowser событие действительно срабатывает?

Попробуйте связать событие до перехода:

то есть поменять местами строки на следующие:

webBrowser1.DocumentCompleted + = webBrowser1_DocumentCompleted;

webBrowser1.Navigate ("http://grooveshark.com/#!/shinningstar1001/collection ");

Кроме того, DocumentCompleted может срабатывать для каждого дочернего документа (например, таблицы стилей CSS), поэтому убедитесь, что вы перехватываете событие для URL-адреса, который вам нужен.

void BrowserDocumentCompleted(object sender,
        WebBrowserDocumentCompletedEventArgs e)
{
  if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
    return; 

  //The page is finished loading 
}

Дополнительные сведения см. Здесь: Обнаружение полной загрузки страницы WebBrowser

Окончательное решение - контент передается на главную страницу из другого источника, поэтому поиск целевого div - лучшее решение:

 private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // If the ReadyState is Complete then the page or an iFrame within have completed downloading.  
            if (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
                return; 

            // Ensures only the first match of page-content is resturned to the RichTextBox.
            // If this does not contain what you are looking for then you may need to find an 
            // additional way to refine for the content you are after. 
            if (richTextBox1.Text.Length > 0) return;

            // Check to see if we have got the page-content div in our result source 
            // and set the richtextbox if we have it.
            var songList = webBrowser1.Document.GetElementById("page-content");
            if (songList != null)
            {
                richTextBox1.Text = songList.OuterHtml;
            }
        }
person Murray Foxcroft    schedule 30.12.2014
comment
до сих пор не могу получить точный контент, обратитесь к картинке :( - person Sing; 30.12.2014
comment
Но если вы используете инструмент chrome dev и просматриваете сайт, вы можете найти этот идентификатор с помощью Ctrl + f и найти внутри список песен, это то, что я не могу понять. - person Sing; 30.12.2014
comment
В ответ добавлено проверенное решение - ищите окончательное решение - person Murray Foxcroft; 31.12.2014
comment
Вау, спасибо, это потрясающе, но я могу получить около 1/10 списка песен. Пожалуйста, обратитесь к обновленной статье :) - person Sing; 31.12.2014
comment
Привет, Энди, тебе придется продолжать копать в этом. Ответ будет лежать в HTML, используйте инструменты разработчика Chrome для дальнейшего изучения и поиска нужных элементов. - person Murray Foxcroft; 31.12.2014
comment
Я считаю, что количество песен в DOM никогда не меняется, их содержимое меняется динамически, когда я прокручиваю страницу, у вас есть идея получить все это? - person Sing; 02.01.2015
comment
Попробуйте прокрутить окно браузера: social.msdn.microsoft.com/Forums/windows/en-US/ - person Murray Foxcroft; 03.01.2015
comment
Я пробовал, но обнаружил, что это не браузер, а прокручиваемый внутри div, я постараюсь найти способ его прокрутить. Спасибо за вашу помощь:) - person Sing; 05.01.2015