5

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.

An image showing what the OP wants his screenshot to look like

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"
ruffin
  • 16,507
  • 9
  • 88
  • 138
user3421341
  • 101
  • 2
  • 6
  • 1
    Why not use something appropriate like PhantomJS to take screenshots from web pages? – Tomalak Oct 23 '14 at 19:57
  • Never tried it before. Moreover, the only tool (language) I am familiar with is Powershell. – user3421341 Oct 23 '14 at 21:10
  • Sure, and there's nothing wrong with solving it in Powershell. I'm just pointing out that tools already exist and might be worthwhile investigating. – Tomalak Oct 23 '14 at 21:12
  • Thanks for letting me know about it, but how could we even start with powershell! I don't even know what to think – user3421341 Oct 23 '14 at 21:15
  • This one too, why are there all the tags other than powershell? They don't seem very related... – AlphaModder Oct 24 '14 at 15:21

2 Answers2

3

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.

ruffin
  • 16,507
  • 9
  • 88
  • 138
  • Thanks a lot for helping Sir! I just realized that using powershell is not a smart and reliable choice for this work. I will have to figure out something else. – user3421341 Oct 24 '14 at 11:58
  • It's worth saying that saying Powershell isn't the right tool is *kind* of like saying .NET isn't the right tool, since you can pretty much do whatever you want with .NET in PS, but it'll take some research. That said, @Tomalak 's suggestion of [PhantomJS](http://phantomjs.org/screen-capture.html) looks really good. – ruffin Oct 24 '14 at 12:59
2

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}})
Community
  • 1
  • 1
Chirishman
  • 327
  • 4
  • 6