我跟着this article,解释了如何使用jQuery为Internet Explorer COM-Object增添趣味。虽然作者使用了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控制台中不打印任何内容。
脚本正确加载,因为可以从浏览器的控制台或execScript()调用jQuery-Functions。
似乎问题是当通过JavaScript进行DOM更改时,通过$ ie.document可用的DOM表示不会更新。但是,在Powerershell中,Internet Explorer COM-Object的行为方式与在Python中的行为方式不同吗?
答案 0 :(得分:2)
在while
循环中,表达式(!$window.jQuery)
始终返回true
,因为$window
是ComObject
而COM对象不像JavaScript对象那样展开,所以即使JavaScript中存在window.jQuery
,它也不会自动在PowerShell中的$window
对象上显示。
我真的找不到使用PowerShell中的jQuery 对象的解决方法,我也有兴趣知道是否有办法做到这一点。请参阅我在此创建的this和this问题。
但我认为这个技巧可以在网页上运行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 :(得分:1)
即使我也无法想办法直接使用JQuery作为对象,下面的内容就像我使用Posh一样接近(我必须将第一个here-string的结尾放在同一行中)为了使代码格式化工作):
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")
答案 2 :(得分:1)
我希望我去年读过这篇文章。我还试图在Windows Scripting Host Environment中集成或“注入”JQuery。还试过Powershell。没有用。 然而,我确实成功地使用IE7,IE8和IE9这个对象“InternetExplorer.Application”。
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
答案 3 :(得分:0)
出于某种原因,我需要使浏览器窗口可见,甚至远程工作 - 没有它,Navigate方法是无法忍受的缓慢和$ ie.Busy属性似乎永远不会返回任何东西,但真的。你不应该这样做,但哦,好吧。
$ie.Visible = $true
检查$ ie.Document.Scripts集合,你可以验证jQuery文件已经加载,但我似乎无法使引用$ ie.Document.parentWindow工作 - 这也意味着我似乎无法得到jQuery属性。它是一个已知属性,但它似乎没有任何有用的东西,因为它在PowerShell中传递。
答案 4 :(得分:0)
您可以查看Invoke-JQuery
的源代码。我已经尝试过了,我可以使用jquery来操作页面,虽然我没有修改脚本来添加jquery。