Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Хочу все знать (http://forum.oszone.net/forumdisplay.php?f=23)
-   -   [решено] Отслеживание изменений на сайте (http://forum.oszone.net/showthread.php?t=329731)

The_Immortal 12-09-2017 01:10 2764184

Отслеживание изменений на сайте
 
Всех приветствую!

Имеется банальная задача, но пока решения для неё я не обнаружил.

В общем, есть html-страница, на которой n-абзацев с текстом следующего содержания:
Цитата:

Число1: 50
Число2: 100
Число3: 150
Число4: 200
...
Все числа с некой периодичностью меняются меняются и мне необходимо отслеживать Число3. Если оно когда-либо не будет равно изначальному значению (например, 100), то необходимо создать алерт. Алерт в моем случае это некое оповещение и очень желательно чтобы это оповещение было по е-мейлу. Проверку на изменение необходимо делать в изолированной автономной программе (т.е. это не должен быть плагин на браузер). Проверка должна быть постоянная с заданной периодичностью.

Я давно использую замечательное ПО - WebSite-Watcher. Но к большому сожалению, с этой задачей программа не справляется...

Хотел у Вас спросить, какое ещё ПО можно использовать для решения данной задачи?

Спасибо!

The_Immortal 12-09-2017 23:32 2764362

Задача нереально сложна или всем просто влом вчитываться? :)

Iska 12-09-2017 23:54 2764365

The_Immortal, если это общедоступная страница — приведите ссылку и выложите скриншот, на котором отметьте:
Цитата:

Цитата The_Immortal
мне необходимо отслеживать Число3. »


Busla 13-09-2017 09:30 2764390

The_Immortal, нет для вашей задачи общего решения. Т.е. да - "нереально сложная".

Казбек 13-09-2017 16:31 2764492

The_Immortal,

Я не вникал в соответствие нагугленных мною ссылок вашим дополнительным критериям, но в виду отсутствия вариантов в теме:

Iska 13-09-2017 16:38 2764494

Казбек, ну, какие тут могут быть варианты без конкретики? Токмо такие:
Цитата:

Цитата Busla
нет для вашей задачи общего решения. »

Будут детали — появятся и варианты.

The_Immortal 13-09-2017 17:32 2764505

Iska, я молчал, потому как осваивал основы JS! :D

В общем, страница, увы, не общедоступна, но я смоделировал близкий к сути пример. Число3 рандомизируется при каждом запросе к странице: либо 100, либо 101. В конечной задаче это число может плясать как угодно, но для упрощения я сделал мелкий рандом. Главное условие, повторюсь, алерт должен возникать только когда оно не равно 100.

Iska 13-09-2017 18:10 2764508

The_Immortal, близкий по сути пример, боюсь, не подойдёт. Ибо для правильного ответа желательно знать точное содержимое страницы.

The_Immortal 13-09-2017 18:24 2764512

Iska,
Цитата:

Цитата Iska
близкий по сути пример, боюсь, не подойдёт »

другого, увы, у меня нет.
Цитата:

Цитата Iska
желательно знать точное содержимое страницы. »

Содержимое страницы не критично тут совсем, т.к. решение этого примера практически полностью переносимо на реальную задачу. Есть более серьезные проблемы в этой задаче (о них ниже).

Спрошу тогда прицельно - какие средства вы бы порекомендовали для:

а) парсинга страницы;
б) отправки емейла;
в) организации автономности и периодического чекинга.

Я просто даже не могу представить, как лучше (и проще) к этому подойти. Сможет ли это решить PS или это надо писать полноценное приложение на каком-нибудь структурном/оо языке?
Хотя есть AutoIt :)

Iska 13-09-2017 18:44 2764520

Цитата:

Цитата The_Immortal
Содержимое страницы не критично тут совсем, »

Как раз критично, ибо именно от конкретного содержимого и будет зависеть «путь» по иерархии тэгов или выбор тэгов селекцией.

Цитата:

Цитата The_Immortal
Спрошу тогда прицельно - какие средства вы бы порекомендовали для: »

WSH/PowerShell.

The_Immortal 13-09-2017 19:18 2764527

Iska,
Цитата:

Цитата Iska
Как раз критично, ибо именно от конкретного содержимого и будет зависеть «путь» по иерархии тэгов или выбор тэгов селекцией. »

Я понимаю, и всё же:
Цитата:

Цитата The_Immortal
решение этого примера практически полностью переносимо на реальную задачу »

Если точнее, то есть уникальный div ("div3"), внутри которого можно найти искомый текст и разобрать его (обновил код). Т.е. ирархия и вложенность тут вообще не нужна. Нужно тупо обнаружить строку:
Код:

<div id="div3">Число3: 101</div>
И узнать что там за значение...

Цитата:

Цитата Iska
WSH/PowerShell. »

Понял, будем изучать.

Спасибо!

Iska 13-09-2017 23:23 2764572

Цитата:

Цитата The_Immortal
Если точнее, то есть уникальный div ("div3"), »

Ну, вот, видите — совсем другое дело.

Цитата:

Цитата The_Immortal
Т.е. ирархия и вложенность тут вообще не нужна. »

По-разному.

Попробуйте для начала WSH:
Скрытый текст
Код:

Option Explicit

Const READYSTATE_COMPLETE = 4


Dim objRegExp


Set objRegExp = WScript.CreateObject("VBScript.RegExp")

objRegExp.Pattern = "^Число3: (\d+?)$"

With WScript.CreateObject("InternetExplorer.Application")
        .Visible = False
        .Navigate("http://imm.hldns.ru/")
       
        Do
                WScript.Sleep 100
        Loop Until Not .Busy And .ReadyState = READYSTATE_COMPLETE
       
        WScript.Echo .document.GetElementByID("div3").innerText
       
        If objRegExp.Test(.document.GetElementByID("div3").innerText) Then
                If Not StrComp(objRegExp.Execute(.document.GetElementByID("div3").innerText).Item(0).Submatches.Item(0), "100", vbTextCompare) = 0 Then
                        WScript.Echo "<> 100"
                End If
        Else
                WScript.Echo "Not found"
        End If
       
        .Quit
End With

Set objRegExp = Nothing

WScript.Quit 0


Amigos 14-09-2017 07:31 2764584

Цитата:

Цитата The_Immortal
б) отправки емейла; »

Blat
Цитата:

Цитата The_Immortal
в) организации автономности »

Что есть "автономность"?
Цитата:

Цитата The_Immortal
и и периодического чекинга. »

стандартный планировщик windows.
Если мало - nnCron

The_Immortal 14-09-2017 23:45 2764752

Iska, огромнейшее Вам спасибо за помощь! Но Вы как в воду глядели по поводу иерархии... Она всё же есть :( Я ,ослепленный скорейшим получением решения, по своей глупости слишком абстрагировался от задачи и крайне упростил пример... Прошу меня простить за зря потраченное Вами время.
Теперь же я действительно максимально воссоздал условия.

Как видите, html-структура следующая (на примере двух чисел):
Скрытый текст
Код:

<div class="number">
        <div class="num3">
                <div class="title">
                        <h4 class="string">Число3: </h4>
                </div>
                <div class="value">
                        <h5>101</h5>
                </div>
        </div>
</div>

<div class="number">
        <div class="num4">
                <div class="title">
                        <h4 class="string">Число4: </h4>
                </div>
                <div class="value">
                        <h5>105</h5>
                </div>
        </div>
</div>



Во-первых, тут классы. Во-вторых, общие классы идентичны (class="number"), как и внутренние . Но есть и третье-положительное: никаких регулярок тут не требуется, т.к. значение сидит изолированно в классе "value".

В общем, я попытался вывести нужное значение следующим образом:
Код:

Option Explicit

Const READYSTATE_COMPLETE = 4

Dim list

With WScript.CreateObject("InternetExplorer.Application")
        .Visible = False
        .Navigate("http://imm.hldns.ru/")
       
        Do
                WScript.Sleep 100
        Loop Until Not .Busy And .ReadyState = READYSTATE_COMPLETE

        list = .document.getElementsByClassName("num3")(0)
        WScript.Echo list.getElementsByClassName("value")(0).innerText
       
        .Quit
End With

Set objRegExp = Nothing

WScript.Quit 0

Однако получаю странную ошибку (Требуется объект '') на строчке:
Код:

WScript.Echo list.getElementsByClassName("value")(0).innerText
Вы не могли бы подсказать, в чем там может быть ошибка? По сути ведь всё верно. По крайней мере я в инете нашел подобные конструкции:
Код:

wscript.echo element.getElementsByClassName("span")(0).innerText
Чем моя хуже? :) Я в list получаю "внутренности" класса "num3". Далее я пытаюсь вывести внутренний текст (искомое значение) по найденному классу "value", который находится внутри list.

Iska 15-09-2017 03:37 2764758

Цитата:

Цитата The_Immortal
Вы не могли бы подсказать, в чем там может быть ошибка? »

Код:

Set list = .document.getElementsByClassName("num3")(0)

The_Immortal 16-09-2017 23:05 2765042

Iska, пожалуйста, гляньте своим профессиональным взглядом на этот простейший код:
Код:

Option Explicit

Const READYSTATE_COMPLETE = 4

Dim list, WshShell

With WScript.CreateObject("InternetExplorer.Application")
        .Visible = False
        .Navigate("http://imm.hldns.ru/")
       
        Do
                WScript.Sleep 100
        Loop Until Not .Busy And .ReadyState = READYSTATE_COMPLETE

        Set list = .document.getElementsByClassName("num3")(0)
        set WshShell = WScript.CreateObject("Wscript.Shell")

        If Not StrComp(list.getElementsByClassName("value")(0).innerText, "100", vbTextCompare) = 0 Then
                WshShell.Run "c:\mailsend\mailsend -кучавсякихразныпараметров", 0, True
        End If
       
        .Quit
End With

WScript.Quit 0

Нужно ли тут чего-то добавить в плане удаление созданных объектов?

А в общем, благодаря Вам задача решена. Я данный скрипт по совету уважаемого Amigos'а запихнул в Планировщик заданий с заданной периодичностью - всё ок.

И ещё хотел сказать насчет программки для консольной отправки почты Blat - при её использовании я обнаружил пару минусов:
  • для SSL-соединений (которые требуют многие публичные почтовые серверы) ей необходимо иметь дополнительное SSL-туннелирование (в этом помогает Stunnel) - не особо критично, однако неудобно;
  • очень странно, но по отправке писем именно по тому адресу, который важен мне (номер_телефона_Билайн@sms.beemail.ru) наблюдались явные проблемы: письма доставлялись с опозданием в 30-60 мин.; не могу знать с чем это связано, т.к. на всякие публичные адреса типа mail.ru, google.ru, yandex.ru, rambler.ru письма падали мгновенно.
Поэтому я воспользовался аналогичной по назначению программкой mailsend, где вышеуказанных минусов не наблюдается.

Iska 17-09-2017 02:59 2765056

Код:

Option Explicit

Const READYSTATE_COMPLETE = 4

Dim objHTMLElementCollection, objHTMLElementCollection2


With WScript.CreateObject("InternetExplorer.Application")
        .Visible = False
        .Navigate("http://imm.hldns.ru/")
       
        Do
                WScript.Sleep 100
        Loop Until Not .Busy And .ReadyState = READYSTATE_COMPLETE
       
        Set objHTMLElementCollection = .document.getElementsByClassName("num3")
       
        If Not objHTMLElementCollection Is Nothing Then
                Set objHTMLElementCollection2 = objHTMLElementCollection.item(0).getElementsByClassName("value")
               
                If Not objHTMLElementCollection2 Is Nothing Then
                        If Not StrComp(objHTMLElementCollection2.item(0).innerText, "100", vbTextCompare) = 0 Then
                                SendMessage
                        End If
                       
                        Set objHTMLElementCollection2 = Nothing
                Else
                        WScript.Echo "Can't parse elements with [value] class name."
                End If
               
                Set objHTMLElementCollection = Nothing
        Else
                WScript.Echo "Can't parse elements with [num3] class name."
        End If
       
        .Quit
End With

WScript.Quit 0

Sub SendMessage()
        Const cdoSendUsingPort = 2
        Const cdoBasic        = 1
       
        Const strPartSchema    = "http://schemas.microsoft.com/cdo/configuration/"
       
        With WScript.CreateObject("CDO.Message")
                With .Configuration.Fields
                        .Item(strPartSchema & "sendusing")        = cdoSendUsingPort
                        .Item(strPartSchema & "smtpauthenticate") = cdoBasic
                        .Item(strPartSchema & "smtpserver")      = "smtp.mail.ru"
                        .Item(strPartSchema & "smtpserverport")  = 465
                        .Item(strPartSchema & "smtpusessl")      = True
                        .Item(strPartSchema & "sendusername")    = "login"
                        .Item(strPartSchema & "sendpassword")    = "password"
                       
                        .Update
                End With
               
                .To            = "to@yandex.ru"
                .From          = "from@mail.ru"
                .Subject      = "Subject"
                .TextBody      = "TextBody"
               
                .Send
        End With
End Sub

Может потребоваться библиотека Collaboration Data Objects.

The_Immortal 19-09-2017 03:38 2765467

Iska,
Цитата:

Цитата Iska
Может потребоваться библиотека Collaboration Data Objects »

Не потребовалась :)

Всё замечательно работает.

Дай Вам Бог здоровья!

The_Immortal 28-09-2017 14:49 2767440

Iska, на одном из ПК с Windows 7 и Office 2013 функция отправки е-мейла не отрабатывает:
Цитата:

Ошибка: Транспорт потерял связь с сервером.
Код: 80040212
Источник: CDO.Message.1
При попытке установить CDO 1.2.1 (ссылку на который Вы дали выше) выдается следующая ошибка:



Ну оно и логично.

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

Спасибо!

Iska 28-09-2017 15:03 2767443

The_Immortal, не подскажу.

Если Outlook не используется, я бы попробовал удалить этот компонент из установленного комплекта Office и ещё раз попробовал бы установить CDO. Другим вариантом может быть использование объектной модели Microsoft Outlook для создания и отправки письма (мне этот вариант не нравился: не знаю, как в новых версиях, а в старых Outlook «задалбывал» предупреждениями — какая уж там автоматизация).


Время: 13:15.

Время: 13:15.
© OSzone.net 2001-