Jump to content

find specific piece of link in web page


Recommended Posts

Hi everyone, hope you are doing fine :)

Well, I'm currently writing a small script that goes to a certain web page, finds the first link of a specified section and download the file associated to this link.

Depending on the computer that the tool is launched, the script gets the computer model and search in the (provided here) ini file which link to follow.

At first, Dell was kind enough to provide only one link but now, they provide two of them. The first one is now a .txt file ( :( ) whereas my script has been designed to download only the fist and latest link released for the BIOS Update.

image.thumb.png.b0b2db304a35e576187ed37123dc2fcb.png

Here's the current code which is working with only the first and latest link of the BIOS category:

Spoiler
#include <String.au3>
#include <Array.au3>
#include <Date.au3>
#include <InetConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>
#include <WinAPISys.au3>
#include <TrayConstants.au3>
#include <ProgressConstants.au3>
#include <ScreenCapture.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <File.au3>
#Include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <GuiListView.au3>
#include <GuiMenu.au3>
#include <Array.au3>
#include <ButtonConstants.au3>
#include <ColorConstants.au3>
#include <ComboConstants.au3>
#include <ListBoxConstants.au3>
#include <AD.au3>
#Include <EditConstants.au3>
#include <WinAPISys.au3>
#include <IE.au3>

;Script Options
Opt("GUIOnEventMode", 1)
#Requireadmin
;End


;Variable and path declaration / Creation
Global  $a2LinksBIOS, $sModel, $sLinksBIOS, $sBIOSName, $sIniPath, $aSectionsNames, $sURL, $g_DownloadProgress

DirCreate ("C:\SAC_IS\SEE_BIOS_AUTO_UPDATE\Resources\")
FileCopy ("\\xxx\euc_scripts\Resources\SEE.ico", "C:\SAC_IS\SEE_BIOS_AUTO_UPDATE\Resources\SEE.ico", 1)
FileCopy ("\\xxx\euc_scripts\Resources\SAClogo.jpg", "C:\SAC_IS\SEE_BIOS_AUTO_UPDATE\Resources\SAClogo.jpg", 1)
FileCopy ("\\xxx\euc_scripts\Resources\SEE_BIOS_LINKS.ini", "C:\SAC_IS\SEE_BIOS_AUTO_UPDATE\Resources\SEE_BIOS_LINKS.ini", 1)
$sInipath = "C:\SAC_IS\SEE_BIOS_AUTO_UPDATE\Resources\SEE_BIOS_LINKS.ini"
$sImages = "C:\SAC_IS\SEE_BIOS_AUTO_UPDATE\Resources\"
;End

;Model recognition
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"
$sModel=""
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct", "WQL", _
$wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
   $sModel = $objItem.Name
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_ComputerSystemProduct" )
Endif
;End

f_batterycheck()

While 1
   Sleep(10)
Wend

Func f_BatteryCheck()
   $aData = _WinAPI_GetSystemPowerStatus() ;Collect current power status
   If @error Then Return
   If BitAND($aData[1], 8) Then $aData[1] = "Charging"
   If BitAND($aData[1], 128) Then $aData[0] = "Not present"
   If  $aData[0] = "No Power Source" Then ;If not connect to power, display error message
      Msgbox (16, "No Power", "The Laptop must be connected to Power Source!" & @CRLF & "Plug the Laptop to a Power Supply and then relaunch this Tool." & @CRLF & @CRLF & "Program will now exit...")
      Exit
   Else
     f_INI()
   EndIf
EndFunc

Func f_INI()
    $idMsgBox = MsgBox (49, "Attention required", "This tool will automatically download and install the BIOS for this computer." & @CRLF & @CRLF & "This proccess cannot be undone and the computer will be automatically rebooted" & @CRLF & @CRLF & "Click the OK button to go on" & @CRLF & @CRLF & "Click the CANCEL button to save any work in progress. You will have to launch the tool again")
    If $idMsgBox = 2 then Exit
    ;Ini file reading and BIOS download link generation
    $aSectionsNames = IniReadSectionNames ($sInipath) ;Reading all sections in the .ini file
    If Not @Error Then ;If reading was fine
        Local $iPosInArray = _ArraySearch ($aSectionsNames, $sModel) ;Searching for the model in the .ini file
    If @Error  Then ;If model not found
        MsgBox(16, "MODEL DOES NOT MATCH", "The BIOS cannot be downloaded for the " & $sModel & " model!" & @CRLF & @CRLF & "Please contact Enterprise Computing to add it." & @CRLF & @CRLF & "Program will now exit!" & @CRLF & @CRLF & "Error Code: 6 - Model was not found in array") ;Error Message
        Exit ;Program exits
    Else ;If Model found
        If $sModel = "Latitude E7250" Then f_E7250BIOS()
        ; If $sModel = "Latitude 5480" Then f_5480BIOS()
        $sURL = IniRead ($sInipath, $aSectionsNames[$iPosInArray], "URL", "Not found") ;Collecting the download URL in a variable
        $oIE = _IECreate($sURL, 0, 1, 0) ;Creating the URL in an Internet Explorer Object
        Do ;Getting Rid of the Security Popup
        $hWin = WinGetHandle("Security Alert")
        If Not @error Then
            WinClose($hWin)
        EndIf
        Until _IELoadWait($oIE, 0, 100) ;Waiting for the page to be loaded
        _IEQuit($oIE ) ;Closing IE Object
        $sRead = InetRead($sURL) ;Reading the URL
        $aDataBIOS = _StringBetween(BinaryToString($sRead), 'Type: BIOS', 'Category: ') ;Putting data in an array among the BIOS category
        $aLinksBIOS = _StringBetween($aDataBIOS[0], '<TR><TD>', '</TD></TR>') ;Putting data in an array from page source code
        $slinksBIOS = ""
        DirCreate ("C:\Drivers\" & $sModel) ;Creating the download destination folder
        For $i = 0 To UBound($aLinksBIOS) - 1
        If StringInStr($aLinksBIOS[$i], "System BIOS") Then ;Looking in the array the the specified string
            $a2LinksBIOS = _StringBetween($aLinksBIOS[$i], '<A HREF="/', '"><IMG')
            $sLinksBIOS = 'http://downloads.dell.com/' & $a2LinksBIOS[0] ;Creating the BIOS download link
            $sBIOSName = _StringBetween ($a2LinksBIOS[0], "1/", "", $STR_ENDNOTSTART) ;Getting the proper BIOS name
            f_BIOSDownload()
            ExitLoop
        EndIf
        Next
        EndIf
    Endif
EndFunc

;BIOS Download function
Func f_BIOSDownload()
   $s_Totalsize = 0
   $g_DownloadProgress = GUICreate($sModel & " BIOS", 350, 300) ;Creating the GUI
   GUISetBkColor ($Color_White) ;Setting GUI backgroung color to "White"
   GUISetIcon ($sImages & "\SEE.ico") ;Setting the GUI icon
   GUICtrlCreatePic ($sImages & "\SAClogo.jpg", 80, 27, 183, 59) ;Setting a picture in the GUI
   $label1 = GUICtrlCreateLabel ("Downloading the " & $sModel & " latest BIOS", 10, 120, 290, 20) ;Creating first label
   $Label2 = GUICtrlCreateLabel ("", 10, 210, 200, 20) ;Creating an empty label for %age
   $Label3 = GUICtrlCreateLabel ("Filename is: " & ">>> " & $sBIOSName[0] & " <<<", 10, 150, 290, 20)
   $Progress1 = GUICtrlCreateProgress (10, 170, 330, 20) ;Creating the Progress Bar
   $idCancelBtn = GuiCtrlCreateButton ("Cancel Download and Exit Program", 80, 240, 200, 50) ;Creating the "Locate BIOS" button
   GUICtrlSetOnEvent ($idCancelBtn, "_exit")
   GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")
   GUISetState() ;Displaying the BIOS download GUI.
   $url= $sLinksBIOS
   $dir= "C:\Drivers\" & $sModel & "\" & $sBIOSName[0]
   $download = InetGet($url, $dir, 1, 1) ;Downloading the BIOS
   While Not InetGetInfo($download, 2)
      Sleep(200)
      $mbGot = Round(InetGetInfo($download, 0) / 1048576, 2) ;Getting the BIOS size in MB
      If $mbGot > 0 Then
         If $s_Totalsize = 0 Then
            $s_Totalsize = Round(InetGetInfo($download, 1) / 1048576, 2)
         EndIf
         $percentage = Round($mbGot / $s_Totalsize * 100) ;Calculating %age left
         GUICtrlSetData($Progress1, $percentage) ;Making the Progress bar progressing
         GUICtrlSetData($label2, $mbGot & " MB out of " & $s_Totalsize & " MB --> " & $percentage & " %") ;Displaying MB left to download
         If $percentage >= 100 Then
            Sleep (1000)
            f_Execute()
         EndIf
      EndIf
   WEnd
EndFunc
;End



Func f_E7250BIOS()
$oIE = _IECreate("http://downloads.dell.com/published/pages/latitude-e7250-ultrabook.html", 0, 0, 1, 0)
    _IELoadWait($oIE)
    _IEQuit ( $oIE )
    $sRead = InetRead('http://downloads.dell.com/published/pages/latitude-e7250-ultrabook.html')
    $aDataBIOS = _StringBetween(BinaryToString($sRead), 'Type: BIOS', 'Category: ')
    $aLinksBIOS = _StringBetween($aDataBIOS[0], '<TR><TD>', '</TD></TR>')
    $slinksBIOS = ""
    DirCreate ("C:\Drivers\E7250")
    For $i = 0 To UBound($aLinksBIOS) - 1
        If StringInStr($aLinksBIOS[$i], "E7250 System BIOS") Then
            $a2LinksBIOS = _StringBetween($aLinksBIOS[$i], '<A HREF="/', '"><IMG')
            $sLinksBIOS = 'http://downloads.dell.com/' & $a2LinksBIOS[0]
            $sBIOSName = _StringBetween ($a2LinksBIOS[0], "1/", "", $STR_ENDNOTSTART)
            f_E7250BIOSDownload()
            ExitLoop
        EndIf
    Next
EndFunc



;Execute Function
Func f_Execute()
   GUISetState (@SW_HIDE, $g_DownloadProgress)
   Local Const $sFilePath = "C:\Drivers\" & $sModel & "\" & $sBIOSName[0]
   Run(@Comspec & " /c" & FileGetShortName($sFilePath), "", @SW_HIDE)
   WinWaitActive ("BIOS Update Program")
EndFunc
;End

;Exit Function
Func _exit()
   Exit
EndFunc
;End

 

So the question is: 

In the case of double links like shown in the picture above, how it is possible to tell the script to download only the link containing an the .exe file?

Of course, I could have changed the array result to [1] instead of [0] [which is working] but it seems that Dell does that randomly and that I deal with a lot of computer models.

Thanks for the help you can provide, 

-31290-

 

SEE_BIOS_LINKS.ini

Edited by 31290
removed server names

~~~ Doom Shall Never Die, Only The Players ~~~

Link to comment
Share on other sites

You should be able to do this with the standard IE UDF commands. Here's an example --

#include <ie.au3>

Example()

Func Example()
    Local $oIE = _IECreate("http://downloads.dell.com/published/pages/latitude-12-5280-laptop.html", 1)
    Local $oDiv = _IEGetObjById($oIE, "Drivers-Category.BI")
    Local $oTable = _IETagNameGetCollection($oDiv, "Table", 0)
    Local $oRow = _IETagNameGetCollection($oTable, "TR", 1)
    Local $oCell = _IETagNameGetCollection($oRow, "TD", 5)

    Local $oLinks = _IETagNameGetCollection($oCell, "A")

    ConsoleWrite("Found " & $oLinks.length & " links!" & @CRLF)

    For $oLink In $oLinks
        ConsoleWrite($oLink.href & @CRLF)
    Next
EndFunc   ;==>Example

 

Link to comment
Share on other sites

Hi all, 

Thanks a lot for your inputs :)

To check whether this is a .exe ending link or not, I've simply added 

 

For $oLink In $oLinks
      If StringInStr($oLink.href, ".exe") Then
         ConsoleWrite("Debug: Match!  " & $oLink.href & @LF)
  ;~    Else
  ;~     Do other stuff
      EndIf
    Next

But, taking my InetGet from what was working in my first post code, this is now not working anymore.

$download = InetGet('$oLink.href', $dir, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND) ;Downloading the BIOS

Do I have to somehow transform the "$oLink.href" variable to something else (string or so?) to make that work?

Edited by 31290
format

~~~ Doom Shall Never Die, Only The Players ~~~

Link to comment
Share on other sites

10 minutes ago, Danp2 said:

@31290 Remove the quotes around '$oLink.href' and your InetGet should work. :)

Danp2, 

Yes, this is true, no need to add the quotes, my bad :)
How could I have missed that.

Many thanks for your help, all of you!

-31290-

~~~ Doom Shall Never Die, Only The Players ~~~

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...