С помощью Аэдорна Вараниса я работаю над Firefox в
Linux.
Аедорн прислал мне метод входа в систему, который выдает команду jssh, которая
проверяет диалоговое окно «Требуется аутентификация» и, если оно существует, заполняет
в имени пользователя / пароле и отправляет диалог.
Я скопировал и вставил то, что он послал мне ниже:
Вы используете метод, который выглядит следующим образом:
def logon(username, password, wait=3)
jssh_command = "var length = getWindows().length; var win;var found=false; for(var i = 0; i < length; i++) { win = getWindows()[i]; if(win.document.title == \"Authentication Required\") { found = true; break; }} if(found) { var jsdocument = win.document; var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];"
jssh_command << " jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";"
jssh_command << " jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";"
jssh_command << " dialog.getButton(\"accept\").click(); }\n"
sleep(wait)
$jssh_socket.send(jssh_command,0)
read_socket()
wait()
end
Тогда вы можете позвонить в его собственное
нить просто до заходит на сайт
с требованием входа в систему:
Thread.new { logon(user, pass) }
@ff.goto("http://some_url.com")
sleep 3
Увеличьте время ожидания и сна, если
страница загружается некоторое время. Если твой
основной процесс пытается запустить в то время как
команда отправляется через JSSH
сокет, он будет глохнуть и сидеть там
навсегда, пока не убьют. Кроме того, нет
реальный способ обнаружить, если
окно аутентификации появляется. Тот
означает, что вы должны убедиться, что это всегда
работает одинаково каждый раз, или это,
тоже вызывает проблемы. Наконец,
метод всегда должен быть в
другой поток, потому что, как только
окно аутентификации появляется, оно
останавливает всю другую обработку, пока
уходит. Кроме этого, это работает.
Из этого я смог создать подкласс класса FireWatir :: Firefox с
новый класс браузера, который поддерживает метод "credentials =", как
Celerity :: Browser делает. Так же, как и при использовании celerity, вы можете сделать:
require 'browser'
browser = Browser.new
browser.credentials = 'user:pass'
browser.goto('http://some.basic.auth.url')
Это автоматически заполнит диалог Basic Auth и войдет в
сайте.
Я разместил содержимое моего файла browser.rb ниже (обратите внимание на это
работает в ruby + firewatir и jruby + celerity в linux):
ENGINE = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
if ENGINE == 'ruby'
require 'firewatir'
class Browser < FireWatir::Firefox
def initialize(options={})
super(options)
@username = nil
@password = nil
end
def credentials=(string)
username, password = string.split(":")
if username.nil? or password.nil?
raise "Invalid credentials: #{string})"
else
@username = username
@password = password
end
end
def goto(url, wait=3)
if @username.nil? and @password.nil?
return super(url)
else
t = Thread.new { logon(@username, @password, wait) }
result = super(url)
t.join
return result
end
end
private
def logon(username, password, wait)
jssh_command = "
var length = getWindows().length;
var win;
var found = false;
for (var i = 0; i < length; i++) {
win = getWindows()[i];
if(win.document.title == \"Authentication Required\") {
found = true;
break;
}
}
if (found) {
var jsdocument = win.document;
var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];
jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";
jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";
dialog.getButton(\"accept\").click();
}
\n"
sleep(wait)
$jssh_socket.send(jssh_command,0)
read_socket()
end
end
elsif ENGINE == 'jruby'
require 'celerity'
class Browser < Celerity::Browser; end
else
raise "Ruby ENGINE '#{ENGINE}' not supported."
end