Как взять данные с web-страницы?

Решение вопросов при работе с TCL скриптами.

Модератор: Модераторы

Как взять данные с web-страницы?

Сообщение tvrsh » 10 июл 2011 18:18

В связи с частыми просьбами отпарсить тот или иной сайт, напишу небольшую инструкцию. Все действия шаблонные, и совсем не сложные, достаточно один раз в это вникнуть и все будет ясно.

В качестве примера будем забирать с главной страницы http://egghelp.ru/ архива информацию о количестве файлов, объеме и количестве закачек:
Файлов в архиве: 511, объем: 54.5 MB. Всего закачек: 302,551.

Для обработки запросов будем использовать http.tcl
В этом примере используется egglib_pub.tcl

Начнем с бинда команды, которая будет вызывать процедуру parsing:
bind pub - !archive parsing

Ну и сама процедура c путлогом об удачной загрузке.:
proc parsing {nick uhost hand chan text} {

}
putlog "parsing.tcl loaded..."


Пока процедура у нас пустая и ничего не выполняет. Для проверки срабатывания бинда добавим внутрь процедуры путлог, который сообщит на о том, что бинд сработал и процедура выполнилась.
proc parsing {nick uhost hand chan text} {
    putlog "bind: OK"
}
putlog "parsing.tcl loaded..."

Проверим, что у нас вышло. Загружаем скрипт и в патилайне видим
[17:27:09] <bionic> [17:22:41] parsing.tcl loaded...

Проверяем бинд, пишем в канале !archive, в патилайне видим:
[17:28:20] <bionic> [17:23:52] bind: OK

Значит все в порядке.

Приступаем к главному и самому сложному.
Следующей строкой указываем юзерагент с которым бот будет конектиться к сайту. В ::http::config может быть много параметров, но пока вам это не надо. Разберетесь чуть позже.
::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"

Далее указываем адрес сайта и таймаут соединения, чтобы бот не вис при обращении к недоступному сайту. Тут тоже кроме адреса и таймаута можно указать другие параметры но и они вам тоже пока не пригодятся.
set parsing_tok [::http::geturl "http://www.egghelp.ru/" -timeout 20000]

Тут в переменную data мы получаем содержимое нашей страницы:
set data [::http::data $parsing_tok]

И удаляем переменные более не используемые в токене:
::http::cleanup $parsing_tok

Проверим, добавив
putlog $data
сразу после закрытия соединения.
Написав команду на канале в патилайне видим:
[17:47:04] <bionic> [17:42:35] bind: OK
[17:47:04] <bionic> [17:42:35] <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
[17:47:04] <bionic> "http://www.w3.org/TR/html4/loose.dtd">
[17:47:04] <bionic> <html>
[17:47:04] <bionic> <head>
[17:47:04] <bionic> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
[17:47:04] <bionic> <title>Ãëàâíàÿ &bull; TCL ñêðèïòû äëÿ Eggdrop/Windrop</title>

Сразу обращаем внимание на то, что в тайтле у нас какая-то фигня с кодировками. Все это делается на боте с suzi патчем. Так что на простом роботе возможно и не будет таких проблем. Для того, чтобы это исправить, надо добавить перед путлогом перекодировку переменной data:
TCL: [ Скачать ] [ Скрыть ]
if {[info exists ::sp_version]} {
    set data [encoding convertfrom cp1251 $data]
} else {
    set data [encoding convertto cp1251 [encoding convertfrom utf-8 $data]]
}

Проверяем еще раз:
[17:54:01] <bionic> <head>
[17:54:01] <bionic> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
[17:54:01] <bionic> <title>Главная &bull; TCL скрипты для Eggdrop/Windrop</title>
[17:54:01] <bionic> <meta http-equiv="Pragma" content="no-cache">

Все в порядке, данные получены и, кажется, с кодировкой все хорошо.
Теперь приступим к "выемке" нужных нам цифр. Для начала превратим все данные в одну строку:
regsub -all -- {\n} $data "" data

Теперь откроем браузером исходный код страницы и посмотрим на ту часть, которую нам надо достать:
HTML4STRICT: [ Скачать ] [ Скрыть ]
<td align="center" class="row">
Файлов в архиве: <b>511</b>, объем: <b>54.5 MB</b>. Всего закачек: <b>302,552</b>.
</td>

Сначала достанем количество файлов:
regexp {Файлов в архиве: <b>(.*?)</b>} $data "" a

Тут в переменную a попадет все, что лежит между
HTML4STRICT: [ Скачать ] [ Скрыть ]
Файлов в архиве: <b>
и
HTML4STRICT: [ Скачать ] [ Скрыть ]
</b>
в переменной data
Также поступаем и с другими цифрами:
regexp {объем: <b>(.*?)</b>} $data "" b
regexp {Всего закачек: <b>(.*?)</b>} $data "" c

В итоге имеем переменные a, b и c в которых находится то, что нам нужно.
Проверим, что мы там подоставали со страницы добавив строку вывода в канал:
putserv "PRIVMSG $chan :$a $b $c"

Пишем команду в канал:
[18:08:35] <tvrsh> !archive
[18:08:35] <@bionic> 511 54.5 MB 302,552

Ну вот, все работает. Теперь можем группировать и оформлять эти данные как нам захочется:
putserv "PRIVMSG $chan :Файлов в архиве: \002$a\002, объем: \002$b\002. Всего закачек: \002$c\002."
putserv "PRIVMSG $chan :В среднем: \002[expr [string map {, ""} $c]/$a]\002 закачек на файл и \002[expr [lindex $b 0]/$a] Mb\002 на файл."

[18:14:38] <tvrsh> !archive
[18:14:38] <@bionic> Файлов в архиве: 511, объем: 54.5 MB. Всего закачек: 302,552.
[18:14:39] <@bionic> В среднем: 592 закачек на файл и 0.10665362035225048 Mb на файл.

А вот итоговый скрипт:
TCL: [ Скачать ] [ Скрыть ]
bind pub - !archive parsing

proc parsing {nick uhost hand chan text} {
    putlog "bind: OK"

    ::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"
    set parsing_tok [::http::geturl http://www.egghelp.ru/]
    set data [::http::data $parsing_tok]
    ::http::cleanup $parsing_tok

    if {[info exists ::sp_version]} {
        set data [encoding convertfrom cp1251 $data]
    } else {
        set data [encoding convertto cp1251 [encoding convertfrom utf-8 $data]]
    }

    regsub -all -- {\n} $data "" data

    regexp {Файлов в архиве: <b>(.*?)</b>} $data "" a
    regexp {объем: <b>(.*?)</b>} $data "" b
    regexp {Всего закачек: <b>(.*?)</b>} $data "" c

    putserv "PRIVMSG $chan :Файлов в архиве: \002$a\002, объем: \002$b\002. Всего закачек: \002$c\002."
    putserv "PRIVMSG $chan :В среднем: \002[expr [string map {, ""} $c]/$a]\002 закачек на файл и \002[expr [lindex $b 0]/$a] Mb\002 на файл."

}
putlog "parsing.tcl loaded..."


Поправки, дополнения и вопросы приветствуются.

Смотрите также Парсинг https при помощи пакета TLS.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение Vertigo » 10 июл 2011 18:30

set parsing_tok [::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"]

тут не обязательно "заворачивать" ::http::config в parsing_tok, так как она ничего не возвращает.
и еще в
set parsing_tok [::http::geturl http://www.egghelp.ru/]
как минимум надо добавить параметр -timeout миллисекунды, например
set parsing_tok [::http::geturl http://www.egghelp.ru/ -timeout 20000]
, тогда бот не зависнет при запросе лежащего сайта.
Ну и ::http::cleanup не закрывает соединение, а удаляет более неиспользуемые переменные в токене. http.tcl получает данные и пишет их в ::http::data. Соединение закрывается само.
И последнее, переменные в регекспе лучше брать одним регекспом - так быстрее и экономичнее :)
Все это ИМХО, конечно, но я бы сделал так.
Аватара пользователя
Vertigo
 
Сообщения: 107
Зарегистрирован: 20 авг 2008 23:49
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 37 раз.
Версия бота: Eggdrop 1.8

Re: Как взять данные с web-страницы?

Сообщение tvrsh » 10 июл 2011 18:41

Спасибо. Чуть подправил первый пост. Попозже покрасивше и почитабельнее его оформлю.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение DmitRex » 10 июл 2011 22:09

Есле я конечно не ошибаюсь, то можно после строки:
regsub -all -- {\n} $data "" data

Добавить строку:
regsub -all {<br>|</br>} $data " " data

Бывает что в исходном коде сайта попадается текст, который бот будет копировать в IRC с не нужным нам кодом типа обработки текста <br></br> <tp></tp> <p></p> и т.п.
[21:54:35] <DmitRex> !test
[21:54:36] <BitXpatch> Не завидуй - почувствуешь гнет над собой,<br>А унизишь кого - он навек пленник твой.<br>Пока можешь, поддерживай ближних в невзгодах,<br>Тот, кому ты помог, будет рядом с тобой.<br>(Перевод: Н.Тенигиной)
Аватара пользователя
DmitRex
 
Сообщения: 50
Зарегистрирован: 14 июл 2010 10:39
Откуда: Владимир
Благодарил (а): 1 раз.
Поблагодарили: 3 раз.
Версия бота: Eggdrop 1.6.21

Re: Как взять данные с web-страницы?

Сообщение Vertigo » 10 июл 2011 23:10

В таком случае лучше уж воспользоваться
regsub -all -- {<.*?>} $data { } data
Это удалит бо́льшую часть html-кода.

За это сообщение автора Vertigo поблагодарил:
DmitRex (10 июл 2011 23:14)
Аватара пользователя
Vertigo
 
Сообщения: 107
Зарегистрирован: 20 авг 2008 23:49
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 37 раз.
Версия бота: Eggdrop 1.8

Re: Как взять данные с web-страницы?

Сообщение tvrsh » 11 июл 2011 00:07

В случае регсабов присутствует некоторый элемент творчества, иногда надо додуматься как правильно разбить текст, по каким тэгам его разбивать. Главное понять несколько основных правил а в остальном все зависит кокретно от хтмл кода.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение tvrsh » 11 июл 2011 20:01

Еще один пример парсинга.
Предположим, что вам понадобились новости футбола на канал. Немного поискав находим удобный сайт с частыми обновлениями: http://m.championat.com/news/football/
Далее делаем так:
TCL: [ Скачать ] [ Скрыть ]
# Указываем юзерагент.
::http::config -useragent "UserAgent"

# Урл и таймаут.
set tok [::http::geturl http://m.championat.com/news/football/ -timeout 15000]

# Получаем содержимое страницы.
set data [::http::data $tok]

# Очищаем токен.
::http::cleanup $tok

# Превращаем данные в одну строку.
regsub -all -- {\n} $data "" data

# Забираем нужную нам часть.
regexp -- {<ul class="news-list">(.*?)</li>} $data "" a

# Удаляем из нее лишние тэги.
regsub -all -- {<.*?>} $a "" a

# Возвращаем перекодированные данные.
return [encoding convertfrom utf-8 $a]


Проверяем с канала:
<tvrsh> $$ ::http::config -useragent "UserAgent"; set tok [::http::geturl http://m.championat.com/news/football/ -timeout 15000]; set data [::http::data $tok]; ::http::cleanup $tok; regsub -all -- {\n} $data "" data; regexp -- {<ul class="news-list">(.*?)</li>} $data "" a; regsub -all -- {<.*?>} $a "" a; return [encoding convertfrom utf-8 $a]
<@bionic> Return: 19:51 Балахнин: игра с "Сеницей" получилась достаточно зрелищной - 19.392 ms.


Работает. Далее упаковвываете это все в таймер, каждые несколько минут проверяете последнюю новость и если на обновилась то выводите в канал.
Вот и все.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение tvrsh » 20 июл 2011 21:50

Это процедура поможет избежать многократного переписывания однотипных строк.
Загрузите ее отдельным скриптом и обращайтесь к ней
set data [web2data адрес_страницы]

В случае каких-либо ошибок процедура вернет 0, если ошибок нет, то вернется HTML код страницы.

TCL: [ Скачать ] [ Скрыть ]
proc web2data { website } {
    package require http
    # Отправляем http запрос, указываем таймаут и используем catch для того, чтобы избежать остановки
    # выполнения процедуры в случае проблем связи с сайтом или ошибок.
    if { [catch { set token [http::geturl $website -timeout 3000]} error] } {
        putcmdlog "web2data: Error: $error"
        # Если указанный адрес не существует.
    } elseif { [http::ncode $token] == "404" } {
        putcmdlog "web2data: Error: [http::code $token]"
        # Проверяем статус запроса, если все хорошо, то в переменной $data оказывается код страницы
    } elseif { [http::status $token] == "ok" } {
        set data [http::data $token]
        # Если время соединения превышено, то пишем в лог об этом.
    } elseif { [http::status $token] == "timeout" } {
        putcmdlog "web2data: Timeout occurred"
        # Тоже самое с остальными ошибками.
    } elseif { [http::status $token] == "error" } {
        putcmdlog "web2data: Error: [http::error $token]"
    }
    # И наконец, освобождаем переменные токена для последующих операций.
    http::cleanup $token
    if { [info exists data] } {
        return $data
    } else {
        return 0
    }
}


Взято на том же замечательном сайте: http://tclhelp.net/unb/24,1#563
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение wr` » 13 апр 2012 13:39

Доброго времени суток,хотел попробовать взять погоду для определенного города,не получилось :(
Не могли бы вы подсказать что я не так делаю?

bind pub - !pdl parsing
proc parsing {nick uhost hand chan text} {
putlog "bind: OK"
}
putlog "pdl.tcl loaded..."

::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"
set pdl_tok [::http::geturl "http://weather.infobot.ru/current/russia/moscow/podolsk.html" -timeout 20000]
set data [::http::data $pdl_tok]
::http::cleanup $pdl_tok

if {[info exists ::sp_version]} {
set data [encoding convertfrom cp1251 $data]
} else {
set data [encoding convertto cp1251 [encoding convertfrom utf-8 $data]]
}


putlog $data

regsub -all -- {\n} $data "" data

regexp -- {Температура <td>(.*?)</td>} $data "" a
regexp -- {Атмосферное давление <td>(.*?)</td>} $data "" b
regexp -- {Относительная влажность <td>(.*?)</td>} $data "" c

putserv "PRIVMSG $chan :Температура $a , Атмосферное давление $b , Относительная влажность $c"



}
putlog "pdl.tcl loaded..."
Аватара пользователя
wr`
 
Сообщения: 121
Зарегистрирован: 26 май 2009 21:17
Благодарил (а): 19 раз.
Поблагодарили: 0 раз.
Версия бота: Eggdrop 1.6.21+suzi

Re: Как взять данные с web-страницы?

Сообщение tvrsh » 13 апр 2012 14:44

Регэкспы неправильно написаны.
Попробуй вот так:
regexp -- {Температура</td><td class=table_param>(.*?)</td>} $data "" a

В хтмл коде между </td> и <td class=table_param> был переход на новую строку. У тебя он заменился на "ничто":
regsub -all -- {\n} $data "" data

Если там помимо перехода на новую строку остались пробелы имеет смысл попробовать так:
regexp -- {Температура</td>.*?<td class=table_param>(.*?)</td>} $data "" a

.*? означает любое количество символов.
Ну и почитай про регулярные выражения. Что обозначают всякие \d \s+ \n и т.д.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.

За это сообщение автора tvrsh поблагодарил:
wr` (13 апр 2012 20:48)
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Парсинг https при помощи пакета TLS.

Сообщение tvrsh » 10 янв 2014 17:42

Парсинг https при помощи пакета TLS.

Что такое TLS можно почитать на этой странице: http://tls.sourceforge.net/

Установка TLS:
Скачиваем и распаковываем:

Конфигурируем:
./configure

или
./configure --with-tcl=/usr/lib/tcl8.x/ --with-tclinclude=/usr/include/tcl8.x/ --with-ssl-dir=/usr/

Устанавливаем:
make
make install

После установки проверяем:
tclsh
% package require tls
1.60
% exit


Для примера заберем данные со страницы https://whatstatus.info/api/status
За основу возьмем итоговый скрипт из первого сообщения этой темы. Немного подправим его заменив бинд и удалив ненужный парсинг страницы.
Комментариями выделены добавленные строки, необходимые для работы с https:

TCL: [ Скачать ] [ Скрыть ]
bind pub - !tls parsing

proc parsing {nick uhost hand chan text} {

    ::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"
    # Регистрируем https сокет
    ::http::register https 443 ::tls::socket
    set parsing_tok [::http::geturl https://whatstatus.info/api/status]
    set data [::http::data $parsing_tok]
    ::http::cleanup $parsing_tok
    # После получения данных освобождаем https сокет
    ::http::unregister https
   
    #Вместо вывода в канал просто посмотрим, что мы получили в пременной $data
    putlog $data
}
putlog "https parsing example loaded..."


Все подключаем, и смотрим в патилайн бота:
<bionic> [13:29:47] https parsing example loaded...
<bionic> [13:29:52] {"site":"0","irc":"0","tracker":"0"}


Все работает. Далее, полученные данные парсим, как это описывалось выше, и выводим их в канал.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение Bart » 22 июн 2014 16:30

Получилось состряпать вот такой скрипт, позволяющий проверять на http://downforeveryoneorjustme.com состояние сайта.(UP/DOWN)
Некоторые куски текста взяты отсюда, некоторые с других тем. Возникло пару вопросов. Буду очень признателен, если кто-то поможет их решить.

TCL: [ Скачать ] [ Скрыть ]
namespace eval testscript {}
foreach p [array names testscript *] { catch {unset testscript($p) } }
#(.chanset #chan +nopubproscript для отключения скрипта).
setudef flag nopubproscript
set testscript(pref) "!"
set testscript(downfcmd) "сайт site проверить down"

#downforeveryoneorjustme
foreach bind [split $testscript(downfcmd) " "] {
bind pub -|- "$testscript(pref)$bind" ::testscript&#058;:down
}
proc ::testscript&#058;:down {nick uhost hand chan text} {
          global testscript botnick
    if {[channel get $chan nopubproscript]} {
        return
    }

if {$text == "" } {putquick "PRIVMSG $chan :Используй: \002!сайт <название сайта>\002 Пример: \002!сайт habrahabr.ru\002";return}
    if {[string is space $text]} {
            return 0
    }
set connect [::http::geturl http://downforeveryoneorjustme.com/$text -timeout "15000"]
set files [::http::data $connect]
::http::cleanup $files
putlog "$nick/$chan/$text"
regsub -all -- {\n} $files "" data
regexp {</a>(.*?)<p>} $data "" a
regsub -all -- {<.*?>} $a "" a
putserv "PRIVMSG $chan $a"
}
putlog "script loaded."


Итог:
[16:12] <~warlock> !сайт myshows.ru
[16:12] <bot> is up.
[16:12] <~warlock> !сайт myshowsssss.ru
[16:12] <bot> looks down from here.

Вопросы:
1. Подскажите, пожалуйста, как прикрутить обработку приватных команд?
2. Как в выводе заменить:
"is up." на Site UP.
"looks down from here." на Site DOWN.
Аватара пользователя
Bart
 
Сообщения: 24
Зарегистрирован: 05 фев 2014 01:35
Благодарил (а): 17 раз.
Поблагодарили: 0 раз.
Версия бота: Eggdrop 1.6.21+suzi

Re: Как взять данные с web-страницы?

Сообщение tvrsh » 09 июл 2014 17:49

Чтобы добавить обработку приватных команд надо сделать так, чтобы для показа была отдельная процедура, и данные в нее передавались с паблик и приватного бинда по отдельности.
Например:
TCL: [ Скачать ] [ Скрыть ]
# Проходим по всем биндам
foreach bind [split $testscript(downfcmd) " "] {
    # Биндим паблик команды:
    bind pub -|- "$testscript(pref)$bind" ::testscript&#058;:down_pub
    # Проверка на возможность работы в привате и бинд приватных команд:
    if {$testscript(msg) >= 1} {
        bind msg -|- "$testscript(pref)$bind" ::testscript&#058;:down_msg
    }
}

Чтобы работал выбор возможности приватных команд, надо добавить в настройки рядом с
set testscript(pref) "!"
строку
set testscript(msg) "1"


Теперь получается что паблик команды отправляются на обработку в процедуру ::testscript::down_pub а приватные в процедуру ::testscript::down_msg
Теперь надо сделать так, чтобы данные, полученные этими процедурами, отправлялись в главную процедуру, в которой и будет происходить все основные преобразования.

TCL: [ Скачать ] [ Скрыть ]
# Процедура обработки паблик команд
proc ::testscript&#058;:testscript_pub {nick uhost hand chan text} {
    variable testscript

    # Тут проверяем наличие флага на канале.
    if {[channel get $chan nopubproscript]} {
        return 0
    }

    # Если все хорошо, то отправляем параметры в главную процедуру.
    ::testscript&#058;:down $nick $uhost $hand $chan $text
}


Делаем процедуру обработки приватных команд
TCL: [ Скачать ] [ Скрыть ]
# Процедура обработки приватных команд.
proc ::testscript&#058;:testscript_msg {nick uhost hand text} {
    variable testscript
    # Тут нет никаких проверок, просто подменяем отправляемый параметр $chan на $nick так как это приват, и отправляем в главную процедуру.
    ::testscript&#058;:down $nick $uhost $hand $nick $text
}


Вот главная процедура, убираем из нее проверку флага, так как она уже есть в предыдущей процедуре.
TCL: [ Скачать ] [ Скрыть ]
    proc ::testscript&#058;:down {nick uhost hand chan text} {
          global testscript botnick
if {$text == "" } {putquick "PRIVMSG $chan :Используй: \002!сайт <название сайта>\002 Пример: \002!сайт habrahabr.ru\002";return}
    if {[string is space $text]} {
            return 0
    }
set connect [::http::geturl http://downforeveryoneorjustme.com/$text -timeout "15000"]
set files [::http::data $connect]
::http::cleanup $files
putlog "$nick/$chan/$text"
regsub -all -- {\n} $files "" data
regexp {</a>(.*?)<p>} $data "" a
regsub -all -- {<.*?>} $a "" a
putserv "PRIVMSG $chan $a"
}


Пробуй, должно работать. Прошу прощения за долгий ответ.
Have fun.
-
Получить помощь можно на каналах #egghelp в сети IrcNet.ru и #eggdrop в сети RusNet(Ключ канала eggdrop).
Перед созданием новой темы внимательно читайте Правила оформления топиков.

За это сообщение автора tvrsh поблагодарил:
Bart (12 июл 2014 00:53)
Аватара пользователя
tvrsh
 
Сообщения: 1230
Зарегистрирован: 19 авг 2008 16:55
Откуда: Russian Federation, Podolsk
Благодарил (а): 6 раз.
Поблагодарили: 130 раз.
Версия бота: Eggdrop 1.6.20+suzi

Re: Как взять данные с web-страницы?

Сообщение Bart » 25 ноя 2014 21:17

Допустим есть код:
HTML4STRICT: [ Скачать ] [ Скрыть ]
<td id="блабла"><span class="ok">текст/текст1</span></td>
<td id="блабла"><span class="ok">текст/текст2</span></td>
</tr>
<tr><td>бла</td>
<td id="блабла"><span class="ok">текст/текст3</span></td>
<td id="блабла"><span class="ok">текст/текст4</span></td>
</tr>
<tr><td>бла</td>
<td id="блабла"><span class="ok">текст/текст5</span></td>
<td id="блабла"> - </td>
</tr>

Как можно отсюда взять одну рандомную строку текст/текст*
regexp -- {<td id="блабла"><span class=".*?">текст/(.*?)</span></td>} $files - a1
Это, по-идее, должно захватить только первую строку "текст/текст1", но остальные строки проигнорируются, а мне нужно одну рандомную взять из всего текста.
Аватара пользователя
Bart
 
Сообщения: 24
Зарегистрирован: 05 фев 2014 01:35
Благодарил (а): 17 раз.
Поблагодарили: 0 раз.
Версия бота: Eggdrop 1.6.21+suzi

Re: Как взять данные с web-страницы?

Сообщение Vertigo » 25 ноя 2014 21:28

Bart писал(а):мне нужно одну рандомную взять из всего текста

Добавляешь все строки из регекспа в список через lappend и потом из этого списка получаешь случайную. Как взять случайную строчку из файла (есть на форуме) - по этому примеру и сделай себе.

Что-то в духе
TCL: [ Скачать ] [ Скрыть ]
set list [list]
foreach line [split $files \n] {
if {[regexp -- {<td id="блабла"><span class=".*?">текст/(.*?)</span></td>} $line - a1]} {
lappend list $a1
}
}
if {![llength $list]} {значит облом с парсером; return}
set randline [lindex $list [rand [llength $list]]]
putserv "PRIVMSG $chan :$randline"
 

За это сообщение автора Vertigo поблагодарил:
Bart (26 ноя 2014 12:55)
Аватара пользователя
Vertigo
 
Сообщения: 107
Зарегистрирован: 20 авг 2008 23:49
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 37 раз.
Версия бота: Eggdrop 1.8

Re: Как взять данные с web-страницы?

Сообщение Bart » 18 дек 2015 16:05

Цель: получить страницу по URL.
Ввожу в патилайн:
.tcl http::register https 443 [list ::tls::socket -request 1 -require 0 -ssl3 1 -tls1 1]; set connect [http::geturl "https://btnstatus.info/api/status/" -timeout 10000]; set files [::http::data $connect]; return "$files"

Получаю:
[15:03:58] [egglib]: Catched BGError: SSL channel "sock6": error: tlsv1 alert internal error
Tcl error: error reading "sock6": software caused connection abort
Что я делаю не так?
Аватара пользователя
Bart
 
Сообщения: 24
Зарегистрирован: 05 фев 2014 01:35
Благодарил (а): 17 раз.
Поблагодарили: 0 раз.
Версия бота: Eggdrop 1.6.21+suzi

Re: Как взять данные с web-страницы?

Сообщение Vertigo » 18 дек 2015 17:18

Bart писал(а): -ssl3 1 -tls1 1

сделай -ssl3 0 и еще -ssl2 0
Они бажные и ее должны использоваться.
Аватара пользователя
Vertigo
 
Сообщения: 107
Зарегистрирован: 20 авг 2008 23:49
Откуда: Москва
Благодарил (а): 0 раз.
Поблагодарили: 37 раз.
Версия бота: Eggdrop 1.8

Re: Как взять данные с web-страницы?

Сообщение Bart » 01 авг 2016 19:50

Привет.
curl --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0" --connect-timeout 10 -s -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "{\"jsonrpc\": \"2.0\", \"method\": \"shows.Top\", \"params\": {\"mode\": \"all\", \"count\":10}, \"id\": 1}" "https://api.myshows.me/v2/rpc/"

Вот ответ мы получаем:
{"jsonrpc":"2.0","result":[{"rank":1,"voted":165522,"show":{"id":7718,"title":"\u0428\u0435\u0440\u043b\u043e\u043a","titleOriginal":"Sherlock","status":"Returning Series","totalSeasons":4,"year":2010,"watching":209656,"voted":123189,"rating":4.79607,"image":"https:\/\/media.myshows.me\/shows\/small\/9\/94\/9492ce09d3a31c32ba559f5936dac888.jpg"}},{"rank":2,"voted":143299,"show":{"id":11945,"title":"\u0418\u0433\u0440\u0430 \u043f\u0440\u0435\u0441\u0442\u043e\u043b\u043e\u0432","titleOriginal":"Game of Thrones","status":"Returning Series","totalSeasons":6,"year":2010,"watching":185576,"voted":101154,"rating":4.76391,"image": и тд.

Есть две проблемы:
1. Не получается сковертировать \u0428\u0435\u0440\u043b\u043e\u043a. Да и в curl такой опции нет.
.tcl encoding convertto utf-8 \u0428\u0435\u0440\u043b\u043e\u043a
Tcl: Шерлок

Но даже если для отдельно взятого слова получится сделать, то для целого списка, который в $connect - не работает.
Получилось это сделать через echo -e, но в скрипт не получается добавить такую опцию.

2. Из полученных данных хотелось бы сделать:
Название Рейтинг Смотрящих Аудитория Сезонов Год URL: (То есть, вот эта таблица https://myshows.me/search/all/)
Например,
<bot> 1. Шерлок(Sherlock) Рейтинг: 4.79607 Смотрящих: 209658 Аудитория: 50.4% Сезонов: 4 Год: 2010 URL: https://myshows.me/view/7718/
<bot> 2. Game of Thrones(Игра престолов) Рейтинг: 4.76391 Смотрящих: 185578 Аудитория: 44.61% Сезонов: 6 Год: 2010 URL: https://myshows.me/view/11945/
Аватара пользователя
Bart
 
Сообщения: 24
Зарегистрирован: 05 фев 2014 01:35
Благодарил (а): 17 раз.
Поблагодарили: 0 раз.
Версия бота: Eggdrop 1.6.21+suzi


Вернуться в TCL скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

cron