Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » VBS/WSH/JS - [решено] Парсинг html-страницы

Ответить
Настройки темы
VBS/WSH/JS - [решено] Парсинг html-страницы

Ветеран


Сообщения: 1639
Благодарности: 50

Профиль | Отправить PM | Цитировать


Изменения
Автор: The_Immortal
Дата: 07-05-2018
Приветствую!

Возникла необходимость отслеживать на сайте фифы доступность билетов. Есть список интересующих матчей, которые нужно мониторить.

Алгоритм придумал следующий:

1. Формирую массив MatchName, состоящий из названий необходимых для отслеживания матчей:
- Матч 01 - Россия : Саудовская Аравия - Москва «Лужники»
- Матч 07 - Аргентина : Исландия - Москва «Спартак»
- Матч 11 - Германия : Мексика - Москва «Лужники»

2. Поочередно получаю в NodeList дивы с классом "header" (див внутри первого столбец таблицы) и заглядываю внутрь каждого (через innerText), сверяя название текущего матча с первым элементом массива MatchName:
Код: Выделить весь код
<div class="header" ng-bind="product.productName">Матч 01 - Россия : Саудовская Аравия - Москва «Лужники»</div>
3. Если название совпало, то каким-то образом перехожу к соседнему диву "col-sm-9 col-xs-12" (второй таблицы) и также каким-то образом изымаю имя класса внутреннго дива для всех 4 квадратов.

Ключевое - это определить класс "class="categoryBox zeroAvailability" - т.е. если этот класс НЕ "zeroAvailability", то далее кидается алерт.

4. Аналогично пройтись по остальным элементам массива MatchName.



Ну в общем, я начал:

Код: Выделить весь код
Option Explicit

Const READYSTATE_COMPLETE = 4 
Const TimeOut = 10000
Const link = "https://tickets.fifa.com/Services/ADService.html?lang=ru"

Dim objNodeList, i, j

Dim MatchName(2)	' массив из искомых названий матчей 
MatchName(0) = "Матч 01 - Россия : Саудовская Аравия - Москва «Лужники»"
MatchName(1) = "Матч 07 - Аргентина : Исландия - Москва «Спартак»"
MatchName(2) = "Матч 11 - Германия : Мексика - Москва «Лужники»"

With WScript.CreateObject("InternetExplorer.Application")
	.Visible = False
	.Navigate(link)
	
	Do
		WScript.Sleep TimeOut	' ожидаем загрузку страницы
	Loop Until Not .Busy And .ReadyState = READYSTATE_COMPLETE
	
	objNodeList = .document.getElementsByClassName("header")	' получаем в NodeList все элементы с указанным классом

	For i = 0 to 2 Step 1
		For j = 0 to objNodeList.length Step 1	' !!! Ошибка: "Требуется объект '[object HTMLCollection]'
			' ...
		Next		
			
	Next	

	Set objNodeList = Nothing
	
	.Quit
End With

WScript.Quit 0

Вопросы следующие:

1. Понять не могу в чем ошибка. objNodeList - это NodeList, который представляет собой массив из Element'ов. Почему я не могу получить длину этого массива?

2. Вопрос касательно общего алгоритма... Может быть как-то задачу попроще можно решить или логика моя пойдет?

3. Если возможно, то подскажите, пожалуйста, каким образом можно перемещаться по соседним div'ам (из пункта 3. алгоритма)?

Спасибо!

Отправлено: 16:55, 07-05-2018

 

Старожил


Сообщения: 250
Благодарности: 51

Профиль | Отправить PM | Цитировать


опишите пожалнйста еще раз текстом задачу кот решаете

WScript это что то о чем некоторым хочется поскоее забыть - продираться через дебри вашего кода чтобы выяснить objective честно не сильно хота. но может быть получится написать с нуля

Отправлено: 23:11, 09-05-2018 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Сообщения: 1639
Благодарности: 50

Профиль | Отправить PM | Цитировать


Serguei Kouzmine,
Цитата Serguei Kouzmine:
опишите пожалнйста еще раз текстом задачу кот решаете »
Вот отсюда со слов "Локализую проблему".

Отправлено: 23:42, 09-05-2018 | #12


Старожил


Сообщения: 250
Благодарности: 51

Профиль | Отправить PM | Цитировать


да вы шутите! - сядьте посидите подумайте и опишите задачу кот вы решаете.

Код: Выделить весь код
# based on: http://forum.oszone.net/thread-334713.html
# objective:
# associate the titles of the matches with the presence of the column
# other than the
# "class="categoryBox zeroAvailability"
# which indicates e.g. lowAvailability

$ie = new-object -com 'internetexplorer.application'
$ie.visible = $true
$target_url = 'https://tickets.fifa.com/Services/ADService.html?lang=ru'
$ie.navigate2($target_url)
# wait for the page to loads
while (($ie.Busy -eq $true ) -or ($ie.ReadyState -ne 4)) { # 4 a.k.a. READYSTATE_COMPLETE
  start-sleep 100
}
$debug =  $false
$documentElement = $ie.document.documentElement

# https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
# $m1 is likely HTMLCollection
$m1 = $documentElement.getElementsByClassName('header')
if ($debug) {
  $m1.item(1)
}

# limit the work to few first nodes
$cnt = 0
$max_items = 100

if ($m1.length -lt $max_items ){
  $max_items = $m1.length - 1
}

1..$m1.length | foreach-object {

 if ($cnt -ge $max_items ) {
   if ($ie -ne  $null) {
     $ie.quit()
     $ie = $null
     return
   }
 } else {
  $cnt = $_
  if ($debug ){
    write-output $cnt
  }
  $e1 = $m1.item($cnt)

  # write-output ( 'Node text: ' + $e1.textContent )
  if ($debug ){
    write-output ( 'Node name: ' + $e1.nodeName ) # DIV
    write-output ( 'Node text: ' + $e1.textContent )
  }
  $e2 = $e1.parentNode
  if ($debug ){
    $e2.innerHTML
    # <div class="header" ng-bind="product.productName">???? 02 -?????? : ??????? - ????????????</div>
  }

  $e3 = $e2.parentNode

  $e4 = $e3.NextSibling.NextSibling

  if ($debug ){
    $e4.textContent
    #     CAT 1
    #     CAT 2
    #     CAT 3
    #     CAT 4
  }

  $m2 = $e4.getElementsByClassName('categoryBox')
  if ($debug ){
    $m2[1].innerHTML
    # CAT 2
    $m2[1].outerHTML
    # <div class="categoryBox zeroAvailability" ng-bind="cat.categoryName" ng-class="cat.availabilityColor">CAT 2</div>
  }
  if ($debug) {
    write-output $m2[0].outerHTML
  }
  if ($debug) {
    $m2 | foreach-object {
      write-output ("class: " + $_.className)

      # write-output ("class: " + $_.getAttribute('class'))
      write-output ("ng-class: " + $_.getAttribute('ng-class'))
      write-output ("context: " + $_.textContent)
    }
  }
  <#  $_.className -match '.*(?:zeroAvailability|lowAvailability).*'  #>
  $m2 | where-object { $_.className -match '.*(?:lowAvailability).*' } |
    foreach-object {
      write-output ('Node2 HTML: ' + $_.outerHTML)
      write-output ('Node 2 context: ' + $e1.textContent)
      write-output ('Node1 text: ' + $e1.textContent )
    }
  }
}
запускаем получаем
Код: Выделить весь код
PS > . .\fifa_tickets.ps1

Node2 HTML: <div class="categoryBox lowAvailability" ng-bind="cat.categoryName"
ng-class="cat.availabilityColor">CAT 1</div>
Node 2 context: Матч 46 - Панама : Тунис - Саранск
Node1 text: Матч 46 - Панама : Тунис - Саранск

Последний раз редактировалось Serguei Kouzmine, 10-05-2018 в 00:11. Причина: пример кода добавлен

Это сообщение посчитали полезным следующие участники:

Отправлено: 00:02, 10-05-2018 | #13


Ветеран


Сообщения: 1639
Благодарности: 50

Профиль | Отправить PM | Цитировать


Serguei Kouzmine, честно попытался разобрать эти закорючкиPowerShell'ьные премудрости, но тяжко... По-прежнему хочу добить своё
Вот то, что конкретно надо мне, сидит у Вас вот в этих строчках:

Код: Выделить весь код
  $m1 = $documentElement.getElementsByClassName('header')

  $e1 = $m1.item($cnt)

  $e2 = $e1.parentNode

  $e3 = $e2.parentNode

  $e4 = $e3.NextSibling.NextSibling

  $m2 = $e4.getElementsByClassName('categoryBox')
Хоть убейте не могу понять как работает NextSibling... После последовательных обращений дважды к родителю $e3 представляет собой элемент <div class="col-sm-3 col-xs-12">, так? Далее Вы делаете два прыжка:
Код: Выделить весь код
$e4 = $e3.NextSibling.NextSibling
- как и куда он прыгает? По идее же нужен один прыжок, чтобы с <div class="col-sm-3 col-xs-12"> перейти на <div class="col-sm-9 col-xs-12">, а у Вас их два почему-то! =|

Iska, Вы не могли помочь мне разобраться почему там требуется два прыжка а не один? Это не дает мне покоя.

Код: Выделить весь код
<div class="row rowBox rowBoxEven">
	<div class="col-sm-3 col-xs-12"> !!! МЫ ВОТ ТУТ!!!
		...
	</div>

        !!!!! ПРЫЖОК !!!!!

	<div class="col-sm-9 col-xs-12">  !!! ХОТИМ СЮДА!!!
		...
	</div>
</div
Сколько прыжков там? Один же! А по факту надо два... Почему же, млин, их там два? Откуда???


Дабы мой вопрос был полностью понятен, я сделал демо, которое отражает суть проблемы - кликните и поймете мой затуп Почему после первого прыжка у нас имя класса "undefined"??? И откуда при этом тип объекта это Text? Там меж div'ами вообще текста как бы нету.

Последний раз редактировалось The_Immortal, 10-05-2018 в 03:35.


Отправлено: 01:38, 10-05-2018 | #14


Старожил


Сообщения: 250
Благодарности: 51

Профиль | Отправить PM | Цитировать


успокойтесь пожалуйста - по-моему это аргуляр не всегда то что видишь F12 есть то что он на самом деле рисует/методом проб и ош.

там просто в финальной версии эти отладочные строки типа
Код: Выделить весь код
$obj.outerHTML
прочищены

Последний раз редактировалось Serguei Kouzmine, 11-05-2018 в 08:23.

Это сообщение посчитали полезным следующие участники:

Отправлено: 08:16, 11-05-2018 | #15


Ветеран


Сообщения: 1639
Благодарности: 50

Профиль | Отправить PM | Цитировать


Цитата Serguei Kouzmine:
успокойтесь пожалуйста »
Нет, я не из тех

Короче, проблема там была в том, что меж див'ами сидят всякие пробелы, вот их свойство NextSibling-то и видит. Узрейте разницу: тыц и тыц. А вообще, в моём случае логичнее прыгать через свойство nextElementSibling: тыц

Большое спасибо за помощь!

Отправлено: 17:13, 11-05-2018 | #16


Ветеран


Сообщения: 27449
Благодарности: 8087

Профиль | Отправить PM | Цитировать


Цитата The_Immortal:
Короче, проблема там была в том, что меж див'ами сидят всякие пробелы, »
Угумс . TextNode'ы. А ещё, вероятно, их наличие зависит от используемой версии IE. Так же, как и свойство .nextElementSibling появляется только с 9-й версии IE.
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:55, 11-05-2018 | #17


Ветеран


Сообщения: 1639
Благодарности: 50

Профиль | Отправить PM | Цитировать


Iska,
Цитата Iska:
их наличие зависит от используемой версии IE »
А причем тут IE? Под разными браузерами будет одна и та же реакция.

Отправлено: 02:10, 12-05-2018 | #18


Ветеран


Сообщения: 27449
Благодарности: 8087

Профиль | Отправить PM | Цитировать


Цитата The_Immortal:
А причем тут IE? »
При том, что раньше он не преображал whitespace'ы в TextNode'ы. Затем, с какой-то версии, начал это делать, и потому реальное состояние DOM теперь не соответствует видимым html-тэгам (да, теперь так, всё, о чём так долго говорили большевики в W3C, свершилось).

Если же Вы про IE вообще — так ведь мы пользуем его библиотеки для получения страницы и последующего разбора DOM.

Цитата The_Immortal:
Под разными браузерами будет одна и та же реакция. »
Вообще-то — нет. И не только под разными браузерами, но даже под разными версиями одного и того же браузера может быть по-разному.
Это сообщение посчитали полезным следующие участники:

Отправлено: 06:43, 12-05-2018 | #19


Ветеран


Сообщения: 1639
Благодарности: 50

Профиль | Отправить PM | Цитировать


Iska,
Цитата Iska:
Вообще-то — нет. И не только под разными браузерами, но даже под разными версиями одного и того же браузера может быть по-разному. »
Ну... Я прогнал вышеуказанный пример под 4-мя браузерами - вывод один и тот же Или Вы что-то другое имели в виду?

Последний раз редактировалось The_Immortal, 14-05-2018 в 02:38.


Отправлено: 23:26, 12-05-2018 | #20



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » VBS/WSH/JS - [решено] Парсинг html-страницы

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
PowerShell - Парсинг HTML, Parser HTML dosperados Скриптовые языки администрирования Windows 6 15-04-2016 08:46
CMD/BAT - Парсинг HTML Smasher Скриптовые языки администрирования Windows 14 25-09-2012 20:45
[решено] Парсинг страницы с редиректом (PHP) Luzuk Вебмастеру 3 16-03-2012 18:06
Отображение HTML страницы в окне assch AutoIt 3 10-08-2009 14:58
Медиа - автозапуск html страницы с CD WChek Хочу все знать 38 09-06-2008 15:23




 
Переход