Powershell: использование jQuery через InternetExplorer.Application - PullRequest
4 голосов
/ 30 октября 2010

Я следовал этой статье , объясняющей, как оживить COM-объект Internet Explorer с помощью jQuery.Хотя автор использовал Python, я хочу сделать что-то подобное в Powershell.

Прямо сейчас у меня есть этот код:

function addJQuery ($browser) {
    $url="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"

    $document = $browser.document
    $window = $document.parentWindow
    $head = @($document.getElementsByTagName("head"))[0]
    $script = $document.createElement("script")
    $script.type = "text/javascript"
    $script.src = $url
    $head.appendChild($script)
    while (!$window.jQuery) {
        sleep -milliseconds 100
    }
    return $window.jQuery
}

$ie = New-Object -comobject InternetExplorer.Application
$ie.visible = $true
$ie.Navigate("https://some.site.com")
while ($ie.busy) {start-sleep -milliseconds 500}
$j = addJQuery $ie

С Fiddler и с помощью коллекции document.scripts, я убедился, чтофайл загружается.Однако сценарий спит вечно, и когда я пытаюсь вывести $ window.jQuery, он ничего не печатает в консоли PowerShell ISE.

Тем не менее сценарий загружен правильно, поскольку функции jQuery можно вызывать из консоли браузера илиvia execScript ().

Кажется, проблема в том, что DOM-представление, доступное через $ ie.document, не обновляется, когда DOM-изменения производятся через JavaScript.Но не должен ли COM-объект Internet Explorer вести себя в Powershell так же, как в Python?

Ответы [ 5 ]

2 голосов
/ 25 сентября 2014

В вашем цикле while выражение (!$window.jQuery) всегда возвращает true, потому что $window - это ComObject, а COM-объекты не являются экспансиями, как объекты JavaScript, поэтому даже если в JavaScript существует window.jQuery, ононе будет автоматически отображаться на объекте $window в PowerShell.

Я действительно не смог найти обходной путь, чтобы сделать jQuery объекты доступными в powershell, и мне также интересно узнатьесли есть способ сделать это.См. этот и этот вопрос, который я создал для этого.

Но я решил использовать этот трюк для запуска javascript / jquery на веб-странице и получения некоторых результатов со страницы в PowerShell:

# some web page with jQuery in it
$url = "http://jquery.com/"

# Use this function to run JavaScript on a web page. Your $jsCommand can
# return a value which will be returned by this function unless $global
# switch is specified in which case $jsCommand will be executed in global
# scope and cannot return a value. If you received error 80020101 it means
# you need to fix your JavaScript code.
Function ExecJavaScript($ie, $jsCommand, [switch]$global)
{
    if (!$global) {
        $jsCommand = "document.body.setAttribute('PSResult', (function(){$jsCommand})());"
    }
    $document = $ie.document
    $window = $document.parentWindow
    $window.execScript($jsCommand, 'javascript') | Out-Null
    if (!$global) {
        return $document.body.getAttribute('PSResult')
    }
}

Function CheckJQueryExists
{
    $result = ExecJavaScript $ie 'return window.hasOwnProperty("$");'
    return ($result -eq $true)
}

$ie = New-Object -COM InternetExplorer.Application -Property @{
    Navigate = $url
    Visible = $false
}
do { Start-Sleep -m 100 } while ( $ie.ReadyState -ne 4 )

$jQueryExists = CheckJQueryExists $ie
echo "jQuery exists? $jQueryExists"

# make a jQuery call
ExecJavaScript $ie @'
    // this is JS code, remember to use semicolons
    var content = $('#home-content');
    return content.text();
'@

# Quit and dispose IE COM
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | out-null
Remove-Variable ie
1 голос
/ 07 ноября 2010

Несмотря на то, что я также не мог придумать способ работать напрямую с JQuery как с объектом, приведенное ниже настолько близко, насколько я мог бы использовать Posh (мне пришлось поместить конец первой строки здесь в той же строке чтобы форматирование кода работало):

function addJQuery ($browser) { 
#helper function to highlight text 
$func=@"
function SelectText(element) { 
    var text = document.getElementById(element); 
    var range = document.body.createTextRange(); 
    range.moveToElementText(text); 
    range.select(); 
}"@ #needs to be at the beginning of the next line
$url='http://code.jquery.com/jquery-1.4.2.min.js'
$document = $browser.document 
$window = $document.parentWindow 
$head = @($document.getElementsByTagName("head"))[0] 
$script = $document.createElement('script') 
$script.type = 'text/javascript'
$script.src = $url 
$head.appendChild($script) | Out-Null
#inject helper function
$script = $document.createElement('script') 
$script.type = 'text/javascript'
$script.text = $func 
$head.appendChild($script) | Out-Null}#end function
$ie = new-object -com internetexplorer.application
$ie.visible = $true
$ie.navigate2("http://www.example.com")
# Wait for page load
while($ie.busy) {start-sleep 1}
# Inject jQuery
addJQuery $ie
#Test whether JQuery is usable
$code1=@"
    `$('a').hide();
"@

$code2=@"
var str=`$('p:first').text();`$('#myResult').html(str);
"@

#add addtional div to store results
$div="<div id='myResult'>"
$ie.Document.body.innerHTML += $div
#hide anchor tag
$ie.document.parentWindow.execScript("$code1","javascript")
#change innerhtml of div
$ie.document.parentWindow.execScript("$code2","javascript")
#retrieve the value
$result = $ie.document.getElementById("myResult") 
$result.innerHtml
#call SelectText function
$ie.document.parentWindow.execScript("SelectText('myResult')","javascript")
1 голос
/ 14 июля 2011

Я хотел бы прочитать это в прошлом году.Я также пытался интегрировать или «внедрить» JQuery в среду сценариев Windows.Также попробовал Powershell.Никто не работал.Однако мне удалось использовать этот объект «InternetExplorer.Application» с IE7, IE8, а теперь и IE9.

try{
    var ie = new ActiveXObject("InternetExplorer.Application");
    ie.navigate(url);
    ie.visible = false;
    ie.left=800; ie.top=0; ie.height=600; ie.width=900; //use this with ie.visible = true;
    do{} while (ie.busy);
}
catch (e){
    console.log("Exception thrown: "+e)
}
finally {
    IE_waitLoad(ie);
    var webpage=ie.document.body.innerHTML ;
    $("#cache").append($(webpage));
    ie.quit();
}

После всего вышесказанного JQuery - ваш друг.Снова !!!

Я нашел эту замечательную функцию "ожидания" где-то в Интернете:

function IE_waitLoad(pIE) {
    var stat, dstart;
    stat = 0;
    while(true){
        if(stat == 0) {
            if(!pIE.Busy){
                if(pIE.Document.readyState == "complete") {
                    dstart = new Date().getTime();
                    stat = 1;
                }
            }
        }else{
            if(!pIE.Busy && pIE.Document.readyState == "complete") {
                if(new Date().getTime() >= dstart + 1000){
                    break;
                }
            }else{
                stat = 0;
            }
        }
        sleep(1000)
    }
}

Функция навигации имеет все эти необязательные параметры

// ie.navigate(url,0x1000);
navOpenInNewWindow = 0x1,
navNoHistory = 0x2,
navNoReadFromCache = 0x4,
navNoWriteToCache = 0x8,
navAllowAutosearch = 0x10,
navBrowserBar = 0x20,
navHyperlink = 0x40,
navEnforceRestricted = 0x80,
navNewWindowsManaged = 0x0100,
navUntrustedForDownload = 0x0200,
navTrustedForActiveX = 0x0400,
navOpenInNewTab = 0x0800,
navOpenInBackgroundTab = 0x1000,
navKeepWordWheelText = 0x2000,
navVirtualTab = 0x4000
0 голосов
/ 17 мая 2012

Вы можете посмотреть исходный код Invoke-JQuery.Я попробовал это и смог использовать jquery для манипулирования страницей, хотя я не модифицировал скрипт для добавления jquery.

0 голосов
/ 02 ноября 2010

По какой-то причине мне нужно было сделать окно браузера видимым, чтобы оно могло работать даже удаленно - без него метод Navigate был бы невыносимо медленным, а свойство $ ie.Busy, казалось бы, никогда не возвращало ничего, кроме True.Вам не нужно этого делать, ну да ладно.

$ie.Visible = $true

Осматривая коллекцию $ ie.Document.Scripts, вы можете убедиться, что файл jQuery загружен, но я не могу сделатьсправочная работа $ ie.Document.parentWindow - это также означает, что я также не могу получить свойство jQuery.Это известное свойство, но, похоже, оно не заполнено чем-либо полезным, поскольку оно передается в PowerShell.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...