Форум программистов, компьютерный форум, киберфорум
Наши страницы
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
1

Парсинг файлов в цикле, обращение на каждом проходе к Awesomium

30.08.2016, 16:14. Просмотров 1160. Ответов 32

Если обрабатываю один файл, то все успешно идет, то есть текст вставляю в браузер Awesomium. Вытаскиваю код и обрабатываю как мне нужно.
Когда идет цикл обработки файлов в Awesomium, работа с браузером должна быть также в каждом проходе.
Однако некоторые файлы не обрабатываются, т.к. цикл видимо не дожидается Awesomium, а идет своим ходом.

Думаю, нужно сделать ожидание в цикле для каждого прохода, пока закончится обработка в Awesomium.
В цикле паузы не помогают с разным значением брал: Threading.Thread.Sleep(5000)

Отлавливание события:
vb.net
1
2
3
4
5
6
Private Sub WebControl1_LoadingFrameComplete(sender As Object, e As FrameEventArgs) Handles WebControl1.LoadingFrameComplete
        If e.IsMainFrame Then
            ' Обработка здесь .................
 
        End If
End Sub
В цикле прописано:
vb.net
1
2
3
                While WebControl1.IsLoading
                    Application.DoEvents()
                End While
Обработку перемещал в цикл, тот же самый результат. Необходимо как-то циклу дождаться, когда загрузится вся страница и обработка выполнится полностью.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.08.2016, 16:14
Ответы с готовыми решениями:

Работа Awesomium в цикле, передача данных и нажатие кнопки в браузере
Необходимо парсить в цикле браузером Awesomium. Передаю данные в цикле For в...

Get и Post запрос в цикле - парсинг 1000 страниц
В интернете очень много примеров на тематику Post и Get запросов, но все...

При каждом проходе брекпойнта функция клика дублируется
Подскажите, почему у меня при каждом проходе брекпойнта <1070px событе клика...

Реализовать сортировку выбором с выводом максимов на каждом проходе
{вырезано} решите пожалуйста, очень прошу, сейчас нужно до утра сдать, очень...

Модифицировать код сортировки так, чтобы на каждом следующем проходе количество сравнений декрементировалось
Помогите разобраться. Нужно модифицировать так, чтобы на втором проходе было 8...

32
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
31.08.2016, 16:49  [ТС] 2
Добавил в цикл строку:
vb.net
1
WebControl1.Source = New Uri("url_адрес-здесь")
Стало обрабатываться 50% файлов, то есть каждый нечетный файл в итерациях цикла:
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
        For parStroka = 0 To DataGridView5.RowCount - 1
            '  Что-то делаем тут ...............
            WebControl1.Source = New Uri("url_адрес-здесь")
            '   Текст вставляем в поле Awesomium (WebControl1)
            WebControl1.ExecuteJavascriptWithResult("document.getElementById('jobtext').value = """ & TextBox5.Text & """")
            '   Нажать кнопку в браузере Awesomium "Проверить"
            WebControl1.ExecuteJavascriptWithResult("document.querySelector('#textspellcheck > a').click();")
            '    Ожидаем завершения загрузки
            While WebControl1.IsLoading
                Application.DoEvents()
            End While
            '  Что-то делаем тут ...............
        Next
Еще код:
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    Private Sub WebControl1_DocumentReady(sender As Object, e As DocumentReadyEventArgs) Handles WebControl1.DocumentReady
        '   Вытаскиваем код из Awesomium
        Try
            Dim html As String = WebControl1.ExecuteJavascriptWithResult("document.getElementsByTagName('html')[0].innerHTML")
            '   Что-то делаем тут ...............
            StatusLabel1.Text = "Обработалось ... "
        Catch ex As Exception
            StatusLabel1.Text = "Процедура DocumentReady"
        End Try
    End Sub
 
    Private Sub WebControl1_LoadingFrameComplete(sender As Object, e As FrameEventArgs) Handles WebControl1.LoadingFrameComplete
        If e.IsMainFrame Then
            StatusLabel1.Text = "Awesomium полность загружен"
        End If
    End Sub
Что дописать, чтоб все файлы обрабатывались, а не каждый второй?
0
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
02.09.2016, 13:31  [ТС] 3
Обнаружил в процедуре
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Private Sub WebControl1_DocumentReady(sender As Object, e As DocumentReadyEventArgs) Handles WebControl1.DocumentReady
        Try
            Dim html As String = WebControl1.ExecuteJavascriptWithResult("document.getElementsByTagName('html')[0].innerHTML")
            Dim doc As New HtmlDocument
            doc.LoadHtml(html)
            Dim semadro As String = ""
 
            For Each table As HtmlNode In doc.DocumentNode.SelectNodes("//*[@id='textcheckresults']/div[1]/table//td[1]")
                Application.DoEvents()
                If table.InnerText <> "" Then
                    semadro = semadro + table.InnerText + ", "
                    keyfraz += 1
                    If keyfraz = 10 Then Exit For      ' Выходим из процедуры если набрали 10 фраз
                End If
            Next
если убрать цикл, то обработка происходит всех файлов, как мне нужно.
Видимо, вычисления идут долго, может быть можно как-то изменить этот последний код?

Добавлено через 18 часов 49 минут
Хоть кто-нибудь скажите свое предположение, почему не работает цикл:
vb.net
1
For Each table As HtmlNode In doc.DocumentNode.SelectNodes........
в процедуре
vb.net
1
Private Sub WebControl1_DocumentReady(sender As Object, e As DocumentReadyEventArgs) Handles WebControl1.DocumentReady
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
02.09.2016, 13:58 4
Цитата Сообщение от Egor2014 Посмотреть сообщение
Хоть кто-нибудь скажите свое предположение, почему не работает цикл:
А выражение точно соответствует непустому набору узлов? Я страницу не видел, поэтому не знаю. А так, если выражение возвращает коллекцию узлов, то можно и без цикла обойтись, правда результат будет таким же.
vb.net
1
        Dim semadro = String.Join(", ", doc.DocumentNode.SelectNodes("//*[@id='textcheckresults']/div[1]/table//td[1]").Select(Function(td) td.InnerText))
1
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
02.09.2016, 14:12  [ТС] 5
Пустых узлов нет, там вытаскиваю ключевые фразы их немало на странице.
Поставил после этого кода:
vb.net
1
TextBox9.Text = "=======================  Мы здесь ================"
В результате TextBox9.Text пустой. Получается процедура WebControl1_DocumentReady полностью игнорирует цикл и вашу строку(((

Вернее, в цикле захватывает каждый нечетный файл.
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
02.09.2016, 14:15 6
Цитата Сообщение от Egor2014 Посмотреть сообщение
Пустых узлов нет
Я не про пустые узлы спросил. А про то, возвращает ли выражение, переданное SelectNodes непустую коллекцию узлов. Иными словами: правильно ли составлено выражение XPath?
0
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
02.09.2016, 14:16  [ТС] 7
XPath верно т.к. обрабатывается в цикле каждый нечетный файл.
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
02.09.2016, 14:22 8
Цитата Сообщение от Egor2014 Посмотреть сообщение
XPath верно т.к. обрабатывается в цикле каждый нечетный файл.
Какой файл? О чем вообще речь идет? Вот приведу простой пример. У меня на страничке есть таблица вот такого содержания
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    <table>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr>
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>
    </table>
Выполняю следующий код
vb.net
1
        MsgBox(String.Join(", ", doc.DocumentNode.SelectNodes("//table//td[1]").Select(Function(td) td.InnerText)))
Выводит 1, 4, 7. Если у тебя выражение правильное, то тоже должно все выводиться.
Попробуй выполнить такой код
vb.net
1
MsgBox(doc.DocumentNode.SelectNodes("//*[@id='textcheckresults']/div[1]/table//td[1]").Count.ToString())
0
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
02.09.2016, 14:27  [ТС] 9
Пардон, я поторопился (ошибку свою исправил) ваш код тоже рабочий, но он также как мой цикл, делает обработку в процедуре WebControl1_DocumentReady лишь на нечетной итерации цикла. Видимо дело в Awesomium (WebControl1) что-то не успевает обновится...
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
02.09.2016, 14:33 10
Egor2014, я пытался разобраться в первых постах, но поскольку картинка вырисовывается неполная, посоветовать что-то не могу. Можешь подробнее описать что ты пытаешься сделать?
0
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
02.09.2016, 14:40  [ТС] 11
Все просто: на компе есть страницы html из них нужно вытащить первые 5 ключевых фраз (семантическое ядро).
Подключаю браузер в форме Awesomium с URL: http://advego.ru/text/seo/
и поочередно файлы прогоняю. Если что-то еще подробнее, пожалуйста, скажите, дополню?
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
02.09.2016, 15:12 12
Egor2014, обработка через один файл происходит из-за того, что у тебя фактически две разные страницы загружаются: одна с пустыми полями для ввода, другая - со статистикой. Когда в обработчике DocumentReady ты пытаешься извлекать статистические данные, то получается это у тебя ровно через раз, в силу того, что на каждой второй странице отсутствуют поля со статистикой. Тебе при обработке надо учесть это обстоятельство.
0
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
02.09.2016, 17:52  [ТС] 13
Ух ты, вы меня еще больше озадачили, не понимаю как так получается... я же ей по циклу в каждой итерации даю нормальные страницы с текстом. Мне казалось Awesomium где-то не успевает обновится... и ему нужно паузу в коде подсунуть или командой какой-то его обновлять в каждом проходе.

Добавлено через 43 минуты
А еще вставил этот код:
vb.net
1
MsgBox(doc.DocumentNode.SelectNodes("//*[@id='textcheckresults']/div[1]/table//td[1]").Count.ToString())
То процедура WebControl1_DocumentReady мне показывает количество 3 раза в каждом проходе.
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
02.09.2016, 20:43 14
Цитата Сообщение от Egor2014 Посмотреть сообщение
я же ей по циклу в каждой итерации даю нормальные страницы с текстом.
Да так-то оно так, только ты забываешь о том, что событие DocumentReady при загрузке этой страницы тоже происходит, а стало быть выполняется код, написанный в его обработчике. А обработчик написан так, как будто в браузере может быть только страница со статистикой.
Таким образом общая канва решения примерно следующая:
  1. Создай очередь с текстами для обработки(или с путями к файлам с этими текстами).
  2. Создай метод, который будет определять, какая из страниц загружена.
  3. В обработчике события DocumentReady проверяешь страницу с помощью метода из пункта 1.
  4. Для страницы с полями для ввода, изымаешь из очереди текст, вводишь его в поле, нажимаешь кнопку.
  5. Для страницы со статистикой, вытаскиваешь нужные данные, сохраняешь, нажимаешь кнопку для ввода нового текста.

Для запуска такого кода тебе понадобится заполнить очередь, и один раз выполнить переход браузера на ту страницу.
1
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
04.09.2016, 09:24  [ТС] 15
diadiavova, как вам отправить личное сообщение?

Добавлено через 21 час 31 минуту
Поставил в очередь файлы с путями:

vb.net
1
Private qMyQueue As New Queue
vb.net
1
2
3
4
 '   Ставим в ОЧЕРЕДЬ файлы
            For parStroka = 0 To DataGridView5.RowCount - 1
                qMyQueue.Enqueue(DataGridView5.Item(0, parStroka).Value)
            Next
Текущую страницу обрабатываю: qMyQueue.Peek()
Прописал в WebControl1_DocumentReady:
vb.net
1
2
3
4
5
6
7
8
9
10
11
 Private Sub WebControl1_DocumentReady(sender As Object, e As DocumentReadyEventArgs) Handles WebControl1.DocumentReady
        Try
            '   Ищем слова: Проанализировать другой текст
            Dim htmld As String = WebControl1.ExecuteJavascriptWithResult("document.getElementsByTagName('html')[0].innerHTML")
            If InStr(1, htmld, "Проанализировать другой текст") <> 0 Then
    Button1_Click(sender, e)  ' Обработка статистики
                Exit Sub
            End If
        Catch ex As Exception
 
        End Try
Но это оказалось неверно, т.к. эта процедура прочитывается несколько раз и столько же раз сохраняет в Button1_Click(sender, e).

Для страницы со статистикой Button1_Click(sender, e), обрабатываю, сохраняю:
В конце меняю текущую:
vb.net
1
2
'   Удаления элемента из очереди
    qMyQueue.Dequeue()
И в конце снова жму кнопку Анализа с новой страницей. Из всего сделанного проходит только 1 итерация.

Главный вопрос, что проверять в WebControl1_DocumentReady?
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
04.09.2016, 10:19 16
Цитата Сообщение от Egor2014 Посмотреть сообщение
vb.net
1
Private qMyQueue As New Queue
Лучше использовать System.Collections.Generic.Queue(Of String).
Цитата Сообщение от Egor2014 Посмотреть сообщение
Но это оказалось неверно, т.к. эта процедура прочитывается несколько раз и столько же раз сохраняет в Button1_Click(sender, e).
Скорей всего на странице есть фреймы, так что проверяй для какой страницы сработало событие.
Цитата Сообщение от Egor2014 Посмотреть сообщение
В конце меняю текущую:
Этот метод не только извлекает строку, но и возвращает ее.
Цитата Сообщение от Egor2014 Посмотреть сообщение
Главный вопрос, что проверять в WebControl1_DocumentReady?
Страницы отличаются, проверяй любое различие. Например крупные заголовки на странице со статистикой размещены в элементе h3, а на странице ввода текста таких элементов вообще нет. Ну вот и воспользуйся этим. Как-то так.
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    Private Sub WebControl1_DocumentReady(sender As Object, e As DocumentReadyEventArgs) Handles WebControl1.DocumentReady
        ' Чтобы избежать обработки фреймов, проверяем, сработало ли это для страницы верхнего уровня
    ' Сначала проверь, в каком виде здесь представлена оригинальная строка, например: присутствует ли в адресе слеш в конце.
        If e.OriginalString = "http://advego.ru/text/seo/" Then
            If Boolean.Parse(WebControl1.ExecuteJavascriptWithResult("!documrnt.querySelector('h3')")) Then
                ' Извлекаем текст из очереди
                ' Вставляем в текстовое поле
                ' Жмем на обработку
            Else
                ' Извлекаем статистику
                ' Проверяем наличие текста в очереди
                ' Если очередь не пуста - жмем в браузере кнопку обработки нового текста
            End If
        End If
 
    End Sub
1
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
04.09.2016, 10:35  [ТС] 17
Если работа идет с очередью, то как ранее у меня был цикл, он уже не нужен?
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
04.09.2016, 10:36 18
Цитата Сообщение от Egor2014 Посмотреть сообщение
Если работа идет с очередью, то как ранее у меня был цикл, он уже не нужен?
Естественно не нужен и я об этом уже писал.
Цитата Сообщение от diadiavova Посмотреть сообщение
Для запуска такого кода тебе понадобится заполнить очередь, и один раз выполнить переход браузера на ту страницу.
0
Egor2014
29 / 8 / 2
Регистрация: 22.10.2013
Сообщений: 375
04.09.2016, 22:14  [ТС] 19
Цитата Сообщение от diadiavova Посмотреть сообщение
Скорей всего на странице есть фреймы, так что проверяй для какой страницы сработало событие.
Фреймов нет, каждый раз WebControl1_DocumentReady прочитывает 2 или 3 раза.
Неудобно отловить окончание работы Private Sub WebControl1_DocumentReady на этом участке:
vb.net
1
2
3
4
5
6
7
8
                Else
                    '---------------------------------------------------------
                    ' Извлекаем статистику
                    ' Проверяем наличие текста в очереди
                    ' Если очередь не пуста - жмем в браузере кнопку обработки нового текста
                    '---------------------------------------------------------
                    '   здесь я вытаскиваю статистику ........................               
                End If
Ставлю счетчик прочитывания Stat:
vb.net
1
2
3
4
5
If Stat >= 2 Then
                        '   Удаления элемента из очереди
                        qMyQueue.Dequeue()
                        АнализИзОчередиToolStripMenuItem_Click(sender, e)
                    End If
Анализ страниц идет нормально, до поры до времени, но на некоторой странице вылетает в браузере с ошибкой: 503 Service Temporarily Unavailable. Это видимо когда раньше времени нажалась кнопка, то есть WebControl1_DocumentReady в это время должен 3 раза был прочитать. Как-то по другому нужно отловить полное окончание WebControl1_DocumentReady.

Кнопку в конце жмем эту же как перед 1 итерацией:
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 Private Sub АнализИзОчередиToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles АнализИзОчередиToolStripMenuItem.Click
 '   На текущий элемент в DataGridView5
        For parStroka = 0 To DataGridView5.RowCount - 1
            If qMyQueue.Peek() = DataGridView5.Item(0, parStroka).Value Then
                DataGridView5.CurrentCell = DataGridView5.Rows(parStroka).Cells(0)
                Exit For
            End If
        Next
        '   Обнуляем - Счетчик заходов WebControl1_DocumentReady
        Stat = 0
        '   Код страницы в TextBox2
        TextBox2.Text = IO.File.ReadAllText(TextBox1.Text + "" + qMyQueue.Peek(), Encoding.UTF8)
        ' ..................
        WebControl1.Source = New Uri("OLD_URL")
  End Sub
0
diadiavova
3761 / 1316 / 414
Регистрация: 11.04.2015
Сообщений: 2,456
Записей в блоге: 35
05.09.2016, 10:34 20
Лучший ответ Сообщение было отмечено Egor2014 как решение

Решение

Цитата Сообщение от Egor2014 Посмотреть сообщение
Фреймов нет, каждый раз WebControl1_DocumentReady прочитывает 2 или 3 раза.
Тогда сделай так
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Private Sub WebControl1_DocumentReady(sender As Object, e As DocumentReadyEventArgs) Handles WebControl1.DocumentReady
        If e.ReadyState = DocumentReadyState.Loaded Then
            If Boolean.Parse(WebControl1.ExecuteJavascriptWithResult("!documrnt.querySelector('h3')")) Then
                ' Извлекаем текст из очереди
                ' Вставляем в текстовое поле
                ' Жмем на обработку
            Else
                ' Извлекаем статистику
                ' Проверяем наличие текста в очереди
                ' Если очередь не пуста - жмем в браузере кнопку обработки нового текста
            End If
        End If
 
    End Sub
0
05.09.2016, 10:34
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2016, 10:34

обращение к RecordSet в цикле for
здраствуйте. у меня вопрос... пытаюсь обратится к RecordSet следующим...

Обращение к TextBox-ам в цикле
Есть 10 TextBox-oв. Можно ли не прописывать все 10 боксов, а к примеру так,...

Обращение к объектам в цикле
Помогите с данным кодом - цель чтобы при наведении курсора на объект выдавала...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru