Парсить чужие сайты — это нудный и не благодарный труд. Обычно для этого продвинутые спамеры и ботоводы используют специальный софт. Например, когда это понадобилось мне я пользовался программой ZennoPoster. Для профессионального использования придётся покупать лицензию. Но для небольших задач, доступна демо версия которая позволяет в процессе тестирования делать небольшие проекты и запускать их, и доступно какой-то период штука для автоматического запуска проектов. Очень много визуального программирования и доступны вставки на языке например C#.
Но если парсить сайты — это лишь небольшая часть скрипта, то можно попытаться обойтись AutoIt.
Обратите внимание, что если появляются ошибки, то надо проверить следующие моменты:
— Скрипт должен выполнятся с правами администратора.
— В зависимости от политик безопасности, возможно сайт придётся занести в доверенную зону.
— Работе скрипта так же может мешать UAC (отключение может помочь)
!!!В 9 строчке (Local $aArray = StringRegExp($oLiHtml,‘( (.*?))’,1)), в конструкции ‘ \ ((.*?) \ )’ убираем пробелы !!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <IE.au3> Local $oIE = _IECreate("http://www.coolcode.ru",0,1,0,1) Sleep(2000) Local $oDiv = _IEGetObjById($oIE, "categories-3") Local $oLis = _IETagNameGetCollection($oDiv, "li") For $oLi In $oLis If StringInStr ($oLi.innerhtml,"Администрирование")>0 Then Local $oLiHtml=_IEPropertyGet($oLi,"innerhtml") Local $aArray = StringRegExp($oLiHtml,' \ ((.*?) \ )',1) Global $Num=$aArray[0] EndIf next MsgBox(0,"",$Num); _IEQuit($oIE) |
И так рассмотрим проект который на сайте CoolCode.Ru пытается посмотреть сколько статей в разделе Администрирование.
Воспользуемся модулем:
1 |
#include <IE.au3> |
Запускаем IE с нашим сайтом:
1 |
Local $oIE = _IECreate("http://www.coolcode.ru",0,1,0,1) |
Параметры по порядку:
«http://www.coolcode.ru» — соответственно url страницы
0 — мы не пытаемся открыть новую вкладку.
1- окно видимо
0 — мы не ожидаем конца загрузки страницы(реклама и социальные кнопки… да ну их)
1 — с делать это окно в фокусе
Ждём 2 секунды
1 |
Sleep(2000) |
это скользкий путь если не важно время выполнения скрипта, то лучше на предыдущей строчке в ожидании конца загрузки поставить 1. Так же для ускорения можно сделать небольшой тюнинг самого IE установить там ADBlock(не забываем выключать на моём сайте, что бы кликать рекламу :)), отключить картинки, убрать CSV, и прочее.
Дальше мы из объекта $oIE выцыпляем объект с id = «categories-3»
1 |
Local $oDiv = _IEGetObjById($oIE, "categories-3") |
Для того, что бы посмотреть код объекта смотрим html страницы, а лучше самого объекта, для этого рекомендую Firefox. Хотя мне хватило Chrome.
Вообще в Autoit нету выцыпления по классу в базовом наборе … прям беда. 🙁
И того у нас в объекте $oDiv содержиться примерно такая беда:
Если бы у нас была такая команда
1 |
ConsoleWrite($oDiv.Outerhtml) |
, то в консоли выдался бы такой текст:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<div class="widget clearfix widget_categories" id="categories-3"><h3 class="heading">Рубрики</h3> <ul> <li class="cat-item cat-item-9"><a href="http://coolcode.ru/admin/">Администрирование</a> (12) <ul class="children"> <li class="cat-item cat-item-6"><a href="http://coolcode.ru/admin/scripts/">Скрипты</a> (9) </li> </ul> </li> <li class="cat-item cat-item-1"><a href="http://coolcode.ru/bez-rubriki/">Без рубрики</a> (2) </li> <li class="cat-item cat-item-27"><a href="http://coolcode.ru/novosti/">Новости</a> (2) </li> <li class="cat-item cat-item-31"><a href="http://coolcode.ru/reshenie-zadach/">Проверка знаний</a> (862) </li> <li class="cat-item cat-item-24"><a href="http://coolcode.ru/proektyi/">Проекты</a> (1) </li> <li class="cat-item cat-item-21"><a href="http://coolcode.ru/tsiklyi-statey/">Циклы статей.</a> (1) </li> <li class="cat-item cat-item-11"><a href="http://coolcode.ru/programming_languages/">Языки программирования</a> (21) <ul class="children"> <li class="cat-item cat-item-12"><a href="http://coolcode.ru/programming_languages/training/">Обучение</a> (17) <ul class="children"> <li class="cat-item cat-item-19"><a href="http://coolcode.ru/programming_languages/training/spravochnaya-informatsiya/">Справочная информация</a> (15) </li> </ul> </li> </ul> </li> </ul> </div> |
Здесь мы видим список <li> объектов, делаем коллекцию $oLis.
1 |
Local $oLis = _IETagNameGetCollection($oDiv, "li") |
Бежим по получившейся коллекции:
1 2 3 |
For $oLi In $oLis ... next |
Здесь мы скатились к простому анализу строк, через регулярные выражения:
!!!В 3 строчке (Local $aArray = StringRegExp($oLiHtml,‘( (.*?))’,1)), в конструкции ‘ \ ((.*?) \ )’ убираем пробелы !!!!
1 2 3 4 |
If StringInStr ($oLi.innerhtml,"Администрирование")>0 Then Local $oLiHtml=_IEPropertyGet($oLi,"innerhtml") Local $aArray = StringRegExp($oLiHtml,' \ ((.*?) \ )',2) EndIf |
В принципе, если вы профессионал в регулярных выражениях, вы бы могли сразу воспользоваться функцией: _INetGetSource из модуля Inet.au3 и просто парсить код страницы. Предыдущие манипуляции просто упрощают задачу.
Итак, я немного отвлёкся. В коде мы бежим по li объектам если мы видим что в этом объекте содержится текст Администрирование, то объект правильный.
1 |
If StringInStr ($oLi.innerhtml,"Администрирование")>0 Then |
Сохраняем его в переменную $oLiHtml значение свойства innerhtml:
1 |
Local $oLiHtml=_IEPropertyGet($oLi,"innerhtml") |
То-есть код внутри тега.
Дальше используем поиск всех значений в скобачках и помещаем их в массив $aArray
!!!Строчка (Local $aArray = StringRegExp($oLiHtml,‘( (.*?))’,1)), пишется без пробелов в конструкции ‘ \ ((.*?) \ )’!!!!
1 |
Local $aArray = StringRegExp($oLiHtml,' \ ((.*?) \ )',2) |
Дальше запихиваем нужное значение в переменную $Num
1 |
Global $Num=$aArray[0] |
Здесь я немного упростил себе задачу, не делаю ни каких проверок, что это именно от раздела Администрирования, но это в принципе и не так важно в этом примере.
Далее мы выводим результат на экран и закрываем окно.
1 2 |
MsgBox(0,"",$Num); _IEQuit($oIE) |
На этом парсинг сайта закончен.
Ну и немного модефицировав код, мы можем получить индекс Доу-Джонса с сайта yahoo
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <IE.au3> Local $oIE = _IECreate("https://beta.finance.yahoo.com/quote/%5EDJI/news",0,0,1,1) ;Sleep(10000) Local $oLis = _IETagNameGetCollection($oIE, "span") For $oLi In $oLis If StringInStr ($oLi.outerhtml,'class="quote-price"')>0 Then Local $oLiHtml=_IEPropertyGet($oLi,"innerhtml") Global $Num=$oLiHtml EndIf next _IEQuit($oIE) MsgBox(0,"",$Num); |
Anton огромное спасибо за столь разборчивое разъяснение по парсингу и помощь по взаимодействию с сайтом!
Подскажи, если стоит задача парсить HTML таблицы примерно со 150 точек в корпоративной сети и желательно звкидывать данные в MSQL, но делать это необходимо постоянно, ~1 раз в минуту (со всех точек), своего рода «мониторинг». Autoit подойдёт для этих целей или лучше смотреть на что-то другое?
Здесь нет простого ответа да или нет. Очень важен контекст.
Но вот как в ребусах найди лишний элемент 🙂
корпоративная сеть как минимум 150 хостов, MSQL, AvtoIT.
И мне не нравиться в этом не именно AvtoIT, а в том раз этот вопрос здесь появился, то в этой конторе нет стандартов, а это плохо. Бросьте заниматься этой задачей, срочно обратите внимание на какой нибудь отраслевой стандарт управления… например сборник рекомендаций ITIL. Это очень поможет конкретно вам и бизнесу в целом. 🙂
Но ладно чёт я разошёлся. В общем AvtoIT вполне может справится с задачей клиента. На данный момент его не совсем тривиально декомпилировать (стандартными утилитами это сделать не получиться, покрайней мере на сегодняшний момент). К тому же если сервер ваш и только вы сможете вносить изменения и не будете бороться с ботами то это может быть вполне стабильно. AvtoIT может «медленно» работать и есть ресурсы… но с учётом что это всё таки веб, вполне должно хватить. В дальнейшем может возникнуть проблема с переходом клиентов на Linux, ну или другую OS например Android. Но начать изучать библиотеку QT, конкретно для этой задачи я рекомендовать не могу… сильно трудо-затратно, особенно если вы не хотите стать программистом…
Вижу только один существенный минус, похвастаться что вы знаете AvtoIT в резюме… мне не помогает ни как админу, ну и тем более как программисту.
В данный момент я бы попытался юзать PowerShell для этой задачи, да это было бы трудно, может быть криво в некоторых местах… но зато можно было бы сказать, что в конторе не только я знаю PowerShell(да и … (без разницы), что там было бы 99% кода на .Net 🙂 во вторых строчка в резюме PowerShell!!! да и в жизни может пригодиться…
Ок спасибо огромное, надо погуглить парсинт на PowerShell 😉
Суть собственно какая, у меня в конторе есть вариант создать некую систему учёта, для этого есть сервер на Win 2008 R2 и около 150 устройств (железяк) с которых нужно постоянно собирать данные. Как и чем никому не важно ( кроме меня 😉 ), руководству нужен итог, чтобы они могли практически в режиме онлайн смотреть сколько того или иного товара находится на какой либо точке в данный (или за период) момент времени.
Исходя из запроса, начинаю рассуждать как можно такое сделать и пришел к выводу, что нужно данные чем либо с парсить и сохранить так чтобы потом можно было на основании этих данных строить графики, таблицы, отчёты и т.д,
Вот я и предположил что собирать данные можно средствами Autoit и к примеру сохранять их в базу MSQL, а уже из базы выводить чем то другим и дальше работать. Но пока главное чем лучше (даже наверное проще) это всё спарсить Autoit, PowerShell, Python, PHP и т.д.
Да именно об этом я и говорю, у вас не задумываются о стандартах, и совершенно не боятся того, что будет если ты это им по навнедряешь, а потом наберёшься опыту и пойдёшь дальше… это очень плохо для конторы… А потому да, думай о себе 🙂 думай какую строчку в резюме ты хочешь 🙂 PowerShell это прокачка админа. Python, PHP — программирование…
AutoIT — я бы юзал только для себя когда быстро что то хочешь сделать себе… по парсить там сайтик на появление новостей, написать какого нибудь простого бота … И на предприятии тоже чего нить ну совсем простое… чтоб на страничку влезало… а то и вообще строчек в 10…
А то я по набил одну дрянь…ещё с тех времён, когда о PowerShell никто и не слыхивал… до сих пор с ней мучаюсь… и прибить жалко.. и развивать смысла нет… так и весит мёртвым грузом на моей совести 🙂
А ну и Python туда же куда и AutoIT… 🙂
ОК, ещё раз большое спасибо !!!
У меня в этой конторе уже есть 1 проект по сбору отчётности с тех самых 150 точек, написанный на Autoit, но там всё просто, пользователь сам запускает приложение, вводит данные и жмёт отправить и всё, а тут эта штука должна крутиться на сервере, как к примеру служба (в смысле постоянно 365 дней в году), к сожалению с PowerShell до этого дела не имел, как у него с такими вещами?
#Логин
$login = «login»
#Пароль
$pass = «pass»
#Тема
$theme = «http://www.guitarplayer.ru/forum/index.php?topic=175948.0»
#Страница для авторизации
$loginpage = «http://www.guitarplayer.ru/forum/index.php?action=login»
#Создаем объект типа InternetExplorer.Application
$ie = New-Object -ComObject InternetExplorer.Application
#Переходим к странице авторизации
$ie.Navigate($loginpage)
#Ждем загрузку страницы
While ($ie.Busy) { Start-Sleep -Milliseconds 400 }
#Выбираем форму авторизации
$forms = $ie.Document.forms.namedItem(«frmLogin»)
#Заполняем поле логин
$forms.item(«user»).value= $login
#Заполняем поле пароль
$forms.item(«passwrd»).value = $pass
#Нажимаем на кнопку — «Войти»
($forms | where {$_.value -eq «Войти»}).click()
#Переходим к теме
$ie.Navigate2($theme)
#Выбираем форму для сообщений
$mess = $ie.Document.forms.namedItem(«postmodify»)
#Заполняем сообщение
$mess.item(«message»).value = «up»
#Нажимаем отправить
$mess.item(«post»).click()
#Завершаем работу
$ie.Quit()
Поясню.. пятница конец рабочего дня впереди выходные с только линуксом дома … поэтому не смогу ничего делать… что то меня расстроило, что у меня нет статьи по парсингу PowerShell ом сайта… так что в ближайшие будни она я думаю появится… и я сотру этот пример сверху…
Как и обещал статья PowerShell. Парсинг сайта или забрать значение с сайта.
Ок, ещё раз спасибо, буду ждать с нетерпением свежей статьи.
P/S/ Подскажи, а здесь нет системы личных сообщений, дабы не захламлять комментариями не совсем относящимися к статье?
неа… здесь пока сильно мало людей, для таких вещей 🙁
есть рубрика вопрос ответ….
если уж совсем что то личное… могу дать почту 🙂
Этот комментарий перенесён в рубрику вопрос-ответ http://coolcode.ru/question/8099/
Статья очень крутая. Скажите а если мне к примеру надо проверить 2000 ссылок на то выдают ли они ошибку 404, можно ли как то настроить что б AutoIt брал ссылку вставлял ее в браузер переходил смотрел к примеру в title если есть 404 он как то логировал ссылку где была 404 пусть вставляет в другой документ или потом вконец все их выдаст в список, вот что то такое возможно слетать? Заранее спасибо.