Powershell Scroll down a webpage / Powershell Screenshot - javascript

How to open a webpage in powershell and scroll down.
Actually I am making a script which will do a network report on its own and give me a screenshot which I want. I can open the webpage and start the test with my script, but I want my script to scroll down so that the correct screenshot could be taken. Please Help.
To be precise, I want my script to open a website called testmy.net and do a network report. I want to take the screenshot of just the report and crop everything else. I would really appreciate any help.
Q) How do I scroll down a webpage in PS? I open the website and I want to scroll down?
Q) How do I take a screenshot of only a particular thing?
(After some research I got some part which could take a screenshot of the whole desktop)
I have attached the screenshot of exact thing I need.
Script Starts Here:
$ie = new-object -comobject InternetExplorer.Application -property `
#{navigate2="http://testmy.net/SmarTest/combinedAuto"; visible = $true}
# Wait for the page to finish loading
$ie.fullscreen = $true
do {sleep 5} until (-not ($ie.Busy))
# Take A ScreenShot (Script taken from Stackflow)
[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
function screenshot([Drawing.Rectangle]$bounds, $path) {
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
$graphics = [Drawing.Graphics]::FromImage($bmp)
$graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
$bmp.Save($path)
$graphics.Dispose()
$bmp.Dispose()
}
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, 1000, 900)
screenshot $bounds "C:\screenshot.png"

I think you're looking for really quick and dirty. If that's true, and you don't mind ugly, try using SendKeys.
$ie = new-object -comobject InternetExplorer.Application -property `
#{navigate2="http://testmy.net/SmarTest/combinedAuto"; visible = $true}
# Wait for the page to finish loading
$ie.fullscreen = $true
do {sleep 5} until (-not ($ie.Busy))
[System.Windows.Forms.Cursor]::Position = New-Object system.drawing.point(700,700)
[System.Windows.Forms.SendKeys]::SendWait({DOWN 10})
# Take A ScreenShot (Script taken from Stackflow)
[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
function screenshot([Drawing.Rectangle]$bounds, $path) {
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
$graphics = [Drawing.Graphics]::FromImage($bmp)
$graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
$bmp.Save($path)
$graphics.Dispose()
$bmp.Dispose()
}
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, 1000, 900)
screenshot $bounds "C:\tmp\screenshot.png"
Keep messing around with the number of down arrows you send until it's right -- so edit {DOWN 10}.
NOTE: Chirishman says that you need to have two squiggle brackets around DOWN 10 -- {{DOWN 10}}. The version above almost certainly worked verbatim on my box at the time of writing, but ymmv.
Scared you're going to have enough timing issues that you eventually go back and use another tool, however. How many of these do you have to take?
Note that I did change the URL to espn.com while testing. Not sure what's going on at yours -- a speed test? Seemed to load about three different pages.

The COM object actually has a scroll control
$HWND = ($objIE = New-Object -ComObject InternetExplorer.Application).HWND
[int]$targetHorizontalScroll = 0
[int]$targetVerticalScroll = 100
[string]$uri = "https://www.test.com"
$objIE.Navigate($uri)
[sfw]::SetForegroundWindow($HWND) | Out-Null
#Omit the next line if running as administrator. Else, see below comment for a link
$objIE = ConnectIExplorer -HWND $HWND
$objIE.Document.parentWindow.scroll($targetHorizontalScroll,$targetVerticalScroll)
This is a much more controlled and repeatable method than sendkeys. When using SendKeys the amount of pixels which you scroll is dependent on the window size, where in this code you scroll an absolute number of pixels, regardless of window size.
My code also uses the ConnectIExplorer function from the answer here:
PowerShell IE9 ComObject has all null properties after navigating to webpage
Which fixes an issue with Protected Mode interfering with scripting of IE Com objects when the script is to be run without elevated permissions.
For convenience, that function by user #bnu is also reproduced here:
function ConnectIExplorer() {
param($HWND)
$objShellApp = New-Object -ComObject Shell.Application
try {
$EA = $ErrorActionPreference; $ErrorActionPreference = 'Stop'
$objNewIE = $objShellApp.Windows() | ?{$_.HWND -eq $HWND}
$objNewIE.Visible = $true
} catch {
#it may happen, that the Shell.Application does not find the window in a timely-manner, therefore quick-sleep and try again
Write-Host "Waiting for page to be loaded ..."
Start-Sleep -Milliseconds 500
try {
$objNewIE = $objShellApp.Windows() | ?{$_.HWND -eq $HWND}
$objNewIE.Visible = $true
} catch {
Write-Host "Could not retreive the -com Object InternetExplorer. Aborting." -ForegroundColor Red
$objNewIE = $null
}
} finally {
$ErrorActionPreference = $EA
$objShellApp = $null
}
return $objNewIE
}
Also it is worth noting that #ruffin's answer contains an error. As written it will type "DOWN 10" instead of sending the down arrow ten times (and accidentally scroll down slightly because it includes a spacebar press). This can be fixed with a second set of curly brackets like so:
[System.Windows.Forms.SendKeys]::SendWait({{DOWN 10}})

Related

Is it possible to avoid breaking on a debugger statement in Chrome?

I'm trying to reverse engineer a heavily obfuscated JS and one of the tricks the author does is to continuously call the debugger statement from within an anonymous function:
Unfortunately, I cannot right click and Never pause it, because each time the function is called a new anonymous function is spawned. The only way for me to inspect the code with DevTools open is to toggle the Disable all breakpoints button, but that disables my breakpoints too.
Is there any way to disable exclusively all debugger statements in Chrome?
In case there isnt, what could be done to bypass this anti-tampering trick?
Download the offending webworker.js file to your local drive, and use a text editor to replace all occurrences of "debugger" with ";".
Then use a Chrome extension to replace the remote resource with your local modified version.
https://chrome.google.com/webstore/detail/resource-override/pkoacgokdfckfpndoffpifphamojphii?hl=en
FYI: I do not endorse the above extension. It was just the first I found via Google.
This answer is for an old Chrome prior to 2021 where we could hack the internals of devtools itself by using devtools-on-devtools:
undock devtools into a separate window
press the full devtools hotkey - CtrlShifti or ⌘⌥i
paste the following code in this new devtools window console and run it
{
const rx = /\bdebugger\b/y;
const eventSymbol = SDK.DebuggerModel.Events.DebuggerPaused;
const original = [...SDK.targetManager._modelListeners.get(eventSymbol)]
.find(v => v.listener.name === '_debuggerPaused');
const debuggerModel = SDK.targetManager.models(SDK.DebuggerModel)[0];
SDK.targetManager.removeModelListener(
SDK.DebuggerModel,
eventSymbol,
original.listener,
original.thisObject);
SDK.targetManager.addModelListener(
SDK.DebuggerModel,
eventSymbol,
async function({data}) {
if (data._debuggerPausedDetails.reason === 'other') {
const frame = data._debuggerPausedDetails.callFrames[0];
const code = await frame._script.requestContent();
let {columnNumber: x, lineNumber: y} = frame._location;
let pos = 0;
while (y--)
pos = code.indexOf('\n', pos) + 1;
rx.lastIndex = Math.max(0, pos + x);
if (rx.test(code)) {
debuggerModel.resume();
return;
}
}
original.listener.apply(original.thisObject, arguments);
});
}
Notes:
You can save this code as a snippet in devtools to run it later.
To quickly switch docking mode in the main devtools press CtrlShiftD or ⌘⇧D
Theoretically, it's not that hard to put this code into resources.pak file in Chrome application directory. There are several tools to decompile/build that file so just add the code to any script that has something like SDK.DebuggerModel.Events.DebuggerPaused inside. One can even write a tool that does that automatically on Chrome update.
Right-click the in the gutter on the line with the debugger statement and select "Never pause here".

Phantomjs: take screenshot of the current page?

I'm trying to use Phantomjs to capture a screenshot from the same page that the user is on.
For example, A user is on my-page.html and has made some changes to the elements of this page, now I need to take a screenshot of an element (DIV) inside this page (my-page.html) and save it.
I found a few examples of Phantomjs and php which I tested and worked on my server and it stores the image on my server too BUT all of the examples I found are for taking screenshots of external pages/URLs and not the 'current page'.
This is fairly a straight forward process in Html2canvas but the quality of the produced image is not good at all so I decided to use Phantomjs to produce higher quality screenshots AND also it allows me to zoom in on the page.
Here is a simple example of using Phantomjs for taking screenshot of External URL's:
var system = require("system");
if (system.args.length > 0) {
var page = require('webpage').create();
page.open(system.args[1], function() {
//viewportSize being the actual size of the headless browser
page.viewportSize = { width: 3000, height: 3000 };
//the clipRect is the portion of the page you are taking a screenshot of
page.clipRect = { top: 0, left: 0, width: 3000, height: 3000 };
page.zoomFactor = 300.0/72.0;
var pageTitle = system.args[1].replace(/http.*\/\//g, "").replace("www.", "").split("/")[0]
var filePath = "img/" + pageTitle + '.png';
page.render(filePath);
console.log(filePath);
phantom.exit();
});
}
Could someone please let me know if this is possible at all?
EDIT (Answer to my own question),
it turns out that you cannot take a screenshot of the current page if the page's elements have been edited by the user on the live basis. the only screenshots you can take with phantomjs is a bare bone of the page.
Reason: phantomjs is a headless browser and uses QtWebKit which runs on the server and it is not a javascript library same as html2canvas.
Explained and experienced by others HERE:
Another use case that is an issue for a project I’m working on is that you need drag and drop. Headless drivers have some basic functionality, but if you need to be able to set precise coordinates you’re stuck with Selenium.
For taking screenshot of current page you must pass the correct URL to Phantom script
Syntax :
phantomjs <"Phantom code url(as in documentation report.js)"> <"page url of which you want to take scrrenshot"> <"result saving url">
Now assuming you are passing correct URL :
In my case I was unable to take screenshot of my page as there was a spring security annotation to it, so it was not letting me to proceed so Please check for any security you added to your page if yes then remove it and then try again.
If case 1 does not apply to you surely there is an problem with URL you are passing please double check it.
Please let me know if problem still persist please post any errors(if occurring) you are getting.

Searching for a Text string on a JavaScript web page with PowerShell

I am trying to search for this string "This update is provided as an Optional update on Windows Update." on this web page "https://support.microsoft.com/en-us/kb/3139923" in PowerShell.
I tried rendering and all possible options and I only get the HTML code back.
I believe the page is using JavaScript code and I do not know how to access that text sentence with PowerShell. I have spent hours looking on the internet and have tried everything I know.
Is there anyway to search that page with PowerShell for that Text Line?
Any help would be greatly appreciated.
You can use the IE com object to do what you need,
$url = "https://support.microsoft.com/en-us/kb/3139923"
$ie = New-Object -com internetexplorer.application;
$ie.visible = $false;
$ie.navigate($url);
While ($ie.Busy)
{Start-Sleep -Seconds 1}
Start-Sleep -Seconds 5;
$div = $ie.Document.getElementById("mt2")
$HasText = $div.innerText -split "[`r`n]" | select-string "This update is provided as an Optional update on Windows Update" -Quiet
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie)
Remove-Variable ie
We browse to the page wait for IE to report its loaded
Wait additional 5 seconds to make sure the scripts have finished loading
We get the DIV that has the data we need.
.innerText shows just the text in the div
Split the text on line breaks and feed it to select-string
Using -Quiet returns true if the text is found so $HasText will be true if the text is on the page.

Acrobat's "This file is already open" message

This is a really strange one. Our company has has an InDesign script that, near the end, calls Acrobat (by way of Applescript) to open a PDF file, replace a page in it, then save the file and close it. We've been using this script for over a year and a half now with no issues on 8 of the 9 computers we have. That last one, however, is giving me an odd message when it tries to open and save the file.
To be clear, all 9 computers are Macs, all running OS X 10.9.5 Mavericks. The script is on a central server, so they're all using the same file:
var unlockCover2014 = app.trustedFunction(function (fName, fPrefix)
{
app.beginPriv();
var folderPrefix = fName.match(/^.*?(?=JOBS)/);
console.println("fName is " + fName);
console.println("folderPrefix is " + folderPrefix);
var myDoc = app.openDoc(folderPrefix + "Product Templates/ProofCoverNew/proof_cover_2014.pdf");
myDoc.replacePages(0, fName, 0, 0);
myDoc.saveAs(fName);
myDoc.closeDoc(true);
app.endPriv();
});
This file is stored in the correct folder to be a Folder-level script. 8 of the computers work through this without any trouble whatsoever. The 9th, however, puts this into Acrobat's Javascript console:
fName is /ArtDept/ArtDept/JOBS/425000-425999/425000 Folder/425000_cover.pdf
folderPrefix is /ArtDept/ArtDept/
RaiseError: This file is already open.
Doc.saveAs:9:
===> This file is already open.
I do not understand why this computer, alone, thinks that the PDF files are open already. The problem that arises from this is that, when the main InDesign script is done running, two documents are still open in Acrobat, and the one it's supposed to save does not get saved.
Any ideas about what's going on here?
I did finally discover what the problem was. I feel a bit silly about how (almost) obvious it is, but perhaps it might help others in my situation.
I disabled the line in the main InDesign script that was calling Acrobat, figuring I'd come back to that problem later after I dealt with some other issues. When I did so and ran the main script again, I discovered that Acrobat does, in fact, already open up a copy of that cover sheet PDF sometime during the execution of the main script! I was shocked, at first, but then I did a headdesk when I quickly realized the cause:
InDesign on this computer is set, by default, to automatically open a PDF after exporting it.
So, I just added a short line to the part of my code that sets the PDF Export Preferences to turn that feature off:
with (app.pdfExportPreferences)
{
pageRange = proofRange;
if (multiColor) pageRange = colorTable.toString();
useSecurity = true;
disallowChanging = true;
disallowCopying = false;
disallowDocumentAssembly = true;
disallowExtractionForAccessibility = false;
disallowFormFillIn = true;
disallowHiResPrinting = false;
disallowNotes = true;
disallowPlaintextMetadata = true;
disallowPrinting = false;
changeSecurityPassword = "(NOPE)";
viewPDF = false;
}
It's the viewPDF line at the end. (Sorry, I don't think I can highlight it with markdown.) I do feel silly that I overlooked such a semi-obvious cause, but I hope this might help someone else who is experiencing a similar issue. Thanks for trying to help anyway, #Loic.
Is it possible that the Acrobat script is ran while InDesign has not totally ended writing the PDF File if this is what we are talking about ? Or maybe there are some network latencies that make the file not reachable for the moment.
I would advice using a delay to (in)validate that theory.
delay 3
On another end, why do you need to replace file. I mean can't this be thought in InDesign Scripting Scope only ? Just curious.

printing protovis output (programmatically)

I'm pondering switching to protovis for visualizations. One thing that keeps me skeptical however - since protovis creates its output as a div in a browser, I wonder if there is any at least semi-automatic way for me to create a bunch of images at once without opening each one and pressing "print" manually.
So the question would be:
do you think I can use a browserless JS engine like V8 to execute the code and print the result?
can I automate opening and printing within a browser?
is there another way to get automated images from protovis?
Thanks,
Nicolas
Have a look at this Google Groups thread about this very topic.
Check out http://www.phantomjs.org/
It is a headless browser.
It can do exactly what you want :
http://code.google.com/p/phantomjs/wiki/QuickStart#Rendering
rasterize.js:
if (phantom.state.length === 0) {
if (phantom.args.length !== 2) {
console.log('Usage: rasterize.js URL filename');
phantom.exit();
} else {
var address = phantom.args[0];
phantom.state = 'rasterize';
phantom.viewportSize = { width: 600, height: 600 };
phantom.open(address);
}
} else {
var output = phantom.args[1];
phantom.sleep(200);
phantom.render(output);
phantom.exit();
}
An example to produce the rendering of the famous Tiger (from SVG):
phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png

Categories

Resources