Показать полную графическую версию : [решено] Отслеживание изменений на сайте
The_Immortal
12-09-2017, 01:10
Всех приветствую!
Имеется банальная задача, но пока решения для неё я не обнаружил.
В общем, есть html-страница, на которой n-абзацев с текстом следующего содержания:
Число1: 50
Число2: 100
Число3: 150
Число4: 200
...Все числа с некой периодичностью меняются меняются и мне необходимо отслеживать Число3. Если оно когда-либо не будет равно изначальному значению (например, 100), то необходимо создать алерт. Алерт в моем случае это некое оповещение и очень желательно чтобы это оповещение было по е-мейлу. Проверку на изменение необходимо делать в изолированной автономной программе (т.е. это не должен быть плагин на браузер). Проверка должна быть постоянная с заданной периодичностью.
Я давно использую замечательное ПО - WebSite-Watcher (http://www.aignes.com/). Но к большому сожалению, с этой задачей программа не справляется...
Хотел у Вас спросить, какое ещё ПО можно использовать для решения данной задачи?
Спасибо!
The_Immortal
12-09-2017, 23:32
Задача нереально сложна или всем просто влом вчитываться? :)
The_Immortal, если это общедоступная страница — приведите ссылку и выложите скриншот, на котором отметьте:
мне необходимо отслеживать Число3. »
The_Immortal, нет для вашей задачи общего решения. Т.е. да - "нереально сложная".
The_Immortal,
Я не вникал в соответствие нагугленных мною ссылок вашим дополнительным критериям, но в виду отсутствия вариантов в теме:
5 Free Tools To Notify You of Website Content Changes (http://www.hongkiat.com/blog/detect-website-change-notification/)
Automatic website change logs and notification (https://www.changedetection.com)
Follow That Page (https://www.followthatpage.com)
Казбек, ну, какие тут могут быть варианты без конкретики? Токмо такие:
нет для вашей задачи общего решения. »
Будут детали — появятся и варианты.
The_Immortal
13-09-2017, 17:32
Iska, я молчал, потому как осваивал основы JS! :D
В общем, страница, увы, не общедоступна, но я смоделировал близкий к сути пример (http://imm.hldns.ru/). Число3 рандомизируется при каждом запросе к странице: либо 100, либо 101. В конечной задаче это число может плясать как угодно, но для упрощения я сделал мелкий рандом. Главное условие, повторюсь, алерт должен возникать только когда оно не равно 100.
The_Immortal, близкий по сути пример, боюсь, не подойдёт. Ибо для правильного ответа желательно знать точное содержимое страницы.
The_Immortal
13-09-2017, 18:24
Iska, близкий по сути пример, боюсь, не подойдёт »
другого, увы, у меня нет. желательно знать точное содержимое страницы. »Содержимое страницы не критично тут совсем, т.к. решение этого примера практически полностью переносимо на реальную задачу. Есть более серьезные проблемы в этой задаче (о них ниже).
Спрошу тогда прицельно - какие средства вы бы порекомендовали для:
а) парсинга страницы;
б) отправки емейла;
в) организации автономности и периодического чекинга.
Я просто даже не могу представить, как лучше (и проще) к этому подойти. Сможет ли это решить PS или это надо писать полноценное приложение на каком-нибудь структурном/оо языке?
Хотя есть AutoIt :)
Содержимое страницы не критично тут совсем, »
Как раз критично, ибо именно от конкретного содержимого и будет зависеть «путь» по иерархии тэгов или выбор тэгов селекцией.
Спрошу тогда прицельно - какие средства вы бы порекомендовали для: »
WSH/PowerShell.
The_Immortal
13-09-2017, 19:18
Iska,Как раз критично, ибо именно от конкретного содержимого и будет зависеть «путь» по иерархии тэгов или выбор тэгов селекцией. »Я понимаю, и всё же: решение этого примера практически полностью переносимо на реальную задачу »Если точнее, то есть уникальный div ("div3"), внутри которого можно найти искомый текст и разобрать его (обновил код (http://imm.hldns.ru/)). Т.е. ирархия и вложенность тут вообще не нужна. Нужно тупо обнаружить строку:<div id="div3">Число3: 101</div>И узнать что там за значение...
WSH/PowerShell. »Понял, будем изучать.
Спасибо!
Если точнее, то есть уникальный div ("div3"), »
Ну, вот, видите — совсем другое дело.
Т.е. ирархия и вложенность тут вообще не нужна. »
По-разному.
Попробуйте для начала 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
б) отправки емейла; » Blat
в) организации автономности » Что есть "автономность"?
и и периодического чекинга. »стандартный планировщик windows.
Если мало - nnCron
The_Immortal
14-09-2017, 23:45
Iska, огромнейшее Вам спасибо за помощь! Но Вы как в воду глядели по поводу иерархии... Она всё же есть :( Я ,ослепленный скорейшим получением решения, по своей глупости слишком абстрагировался от задачи и крайне упростил пример... Прошу меня простить за зря потраченное Вами время.
Теперь же я действительно максимально воссоздал (http://imm.hldns.ru/) условия.
Как видите, 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
Вы не могли бы подсказать, в чем там может быть ошибка? По сути ведь всё верно. По крайней мере я в инете нашел подобные конструкции (https://pastebin.com/BfRYfUAj):wscript.echo element.getElementsByClassName("span")(0).innerText
Чем моя хуже? :) Я в list получаю "внутренности" класса "num3". Далее я пытаюсь вывести внутренний текст (искомое значение) по найденному классу "value", который находится внутри list.
Вы не могли бы подсказать, в чем там может быть ошибка? »
Set list = .document.getElementsByClassName("num3")(0)
The_Immortal
16-09-2017, 23:05
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 (https://www.google.ru/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwir1pzFvqrWAhWmCJoKHTP0B5gQFggnMAA&url=http%3A%2F%2Fwww.blat.net%2F&usg=AFQjCNH4l2X9JTjgEOHf6ZjjGctodtvbDQ) - при её использовании я обнаружил пару минусов:
для SSL-соединений (которые требуют многие публичные почтовые серверы) ей необходимо иметь дополнительное SSL-туннелирование (в этом помогает Stunnel (https://www.google.ru/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwiHxsH0vqrWAhXIE5oKHWNhAxQQFggnMAA&url=https%3A%2F%2Fwww.stunnel.org%2F&usg=AFQjCNHcUFRCtK9qohJAls4h3rkMfbzb7w)) - не особо критично, однако неудобно;
очень странно, но по отправке писем именно по тому адресу, который важен мне (номер_телефона_Билайн@sms.beemail.ru) наблюдались явные проблемы: письма доставлялись с опозданием в 30-60 мин.; не могу знать с чем это связано, т.к. на всякие публичные адреса типа mail.ru, google.ru, yandex.ru, rambler.ru письма падали мгновенно.
Поэтому я воспользовался аналогичной по назначению программкой mailsend (https://github.com/muquit/mailsend/), где вышеуказанных минусов не наблюдается.
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 (http://www.microsoft.com/downloads/details.aspx?FamilyID=2714320d-c997-4de1-986f-24f081725d36&DisplayLang=en).
The_Immortal
19-09-2017, 03:38
Iska, Может потребоваться библиотека Collaboration Data Objects »Не потребовалась :)
Всё замечательно работает.
Дай Вам Бог здоровья!
The_Immortal
28-09-2017, 14:49
Iska, на одном из ПК с Windows 7 и Office 2013 функция отправки е-мейла не отрабатывает:
Ошибка: Транспорт потерял связь с сервером.
Код: 80040212
Источник: CDO.Message.1
При попытке установить CDO 1.2.1 (ссылку на который Вы дали выше) выдается следующая ошибка:
https://content.screencast.com/users/The_Immortal/folders/Snagit/media/053a8083-34fd-4718-a24d-4d19ed3a260f/09.28.2017-14.43.png
Ну оно и логично.
Не подскажите, в чем может быть проблема? Я погуглил, но однозначного решения не увидел...
Спасибо!
The_Immortal, не подскажу.
Если Outlook не используется, я бы попробовал удалить этот компонент из установленного комплекта Office и ещё раз попробовал бы установить CDO. Другим вариантом может быть использование объектной модели Microsoft Outlook для создания и отправки письма (мне этот вариант не нравился: не знаю, как в новых версиях, а в старых Outlook «задалбывал» предупреждениями — какая уж там автоматизация).
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.