简体   繁体   中英

Batch for downloading most recent file (where filename changes on new version) from http website

i need a batch for downloading files from a http website ( http://www.rarlab.com/download.htm ). From this website i only need the most recent version for the 32bit and 64bit english program which is always listed at the top of this website.

Problem 1: There are more than this two files for download on the website

Problem 2: The name of the file changes with every new version

How can i download these 2 files (the most recent version) without knowing the exact file name (and without first visiting the web page to find out the file name) ??

Maybe i can use wget, curl or aria2 for that task but i don't know the parameters/options.

Can anyone help me solving this problem ?

(Please only batch solutions - no vbs, java, jscript, powershell etc.)

thank you.

Sorry, i forgot to say that i use windows 7 32bit. And i prefer batch because the script should be able to run on all windows versions without having to download extra programs or resource kits for different windows version (as of powershell which must be downloaded for windows xp etc.) - and because i only understand batch scripting.

Here's a batch + JScript hybrid script. I know you said no vbs, java, jscript, etc, but you're going to have an awfully hard time scraping HTML with pure batch. But this does meet your other criteria -- running on all Windows versions without having to rely on optional software (like powershell or .Net).* And with JScript's XMLHTTP object you don't even need a 3rd party app to fetch web content.

As for not understanding JScript, aside from a few proprietary ActiveX objects it's just like JavaScript. In case you aren't familiar with JavaScript or regular expressions, I added copious amounts of comments to help you out. Hopefully whatever I didn't bother commenting is pretty obvious what it does.

Update

The script now detects the system locale, matches it with a language on the WinRAR download page, and downloads that language release.

Anyway, save this with a .bat extension and run it as you would any other batch script.

@if (@a==@b) @end /*

:: batch script portion

@echo off
setlocal

set "url=http://www.rarlab.com/download.htm"
set /p "savepath=Location to save? [%cd%] "

if "%savepath%"=="" set "savepath=%cd%"

cscript /nologo /e:jscript "%~f0" "%url%" "%savepath%"

goto :EOF

:: JScript portion */

// populate translation from locale identifier hex value to WinRAR language label
// http://msdn.microsoft.com/en-us/library/dd318693.aspx
var abbrev={}, a=function(arr,val){for(var i=0;i<arr.length;i++)abbrev[arr[i]]=val};
a(['1401','3c01','0c01','0801','2001','4001','2801','1c01','3801','2401'],'Arabic');
a(['042b'],'Armenian');
a(['082c','042c'],'Azerbaijani');
a(['0423'],'Belarusian');
a(['0402'],'Bulgarian');
a(['0403'],'Catalan');
a(['7c04'],'Chinese Traditional');
a(['0c04','1404','1004','0004'],'Chinese Simplified');
a(['101a'],'Croatian');
a(['0405'],'Czech');
a(['0406'],'Danish');
a(['0813','0413'],'Dutch');
a(['0425'],'Estonian');
a(['040b'],'Finnish');
a(['080c','0c0c','040c','140c','180c','100c'],'French');
a(['0437'],'Georgian');
a(['0c07','0407','1407','1007','0807'],'German');
a(['0408'],'Greek');
a(['040d'],'Hebrew');
a(['040e'],'Hungarian');
a(['0421'],'Indonesian');
a(['0410','0810'],'Italian');
a(['0411'],'Japanese');
a(['0412'],'Korean');
a(['0427'],'Lithuanian');
a(['042f'],'Macedonian');
a(['0414','0814'],'Norwegian');
a(['0429'],'Persian');
a(['0415'],'Polish');
a(['0816'],'Portuguese');
a(['0416'],'Portuguese Brazilian');
a(['0418'],'Romanian');
a(['0419'],'Russian');
a(['7c1a','1c1a','0c1a'],'Serbian Cyrillic');
a(['181a','081a'],'Serbian Latin');
a(['041b'],'Slovak');
a(['0424'],'Slovenian');
a(['2c0a','400a','340a','240a','140a','1c0a','300a','440a','100a','480a','080a','4c0a','180a','3c0a','280a','500a','0c0a','040a','540a','380a','200a'],'Spanish');
a(['081d','041d'],'Swedish');
a(['041e'],'Thai');
a(['041f'],'Turkish');
a(['0422'],'Ukranian');
a(['0843','0443'],'Uzbek');
a(['0803'],'Valencian');
a(['042a'],'Vietnamese');

function language() {
    var os = GetObject('winmgmts:').ExecQuery('select Locale from Win32_OperatingSystem');
    var locale = new Enumerator(os).item().Locale;

    // default to English if locale is not in abbrev{}
    return abbrev[locale.toLowerCase()] || 'English';
}

function fetch(url) {
    var xObj = new ActiveXObject("Microsoft.XMLHTTP");
    xObj.open("GET",url,true);
    xObj.setRequestHeader('User-Agent','XMLHTTP/1.0');
    xObj.send('');
    while (xObj.readyState != 4) WSH.Sleep(50);
    return(xObj);
}

function save(xObj, file) {
    var stream = new ActiveXObject("ADODB.Stream");
    with (stream) {
        type = 1; // binary
        open();
        write(xObj.responseBody);
        saveToFile(file, 2); // overwrite
        close();
    }
}

// fetch the initial web page
var x = fetch(WSH.Arguments(0));

// make HTML response all one line
var html = x.responseText.split(/\r?\n/).join('');

// create array of hrefs matching *.exe where the link text contains system language
var r = new RegExp('<a\\s*href="[^"]+\\.exe(?=[^\\/]+' + language() + ')', 'g');
var anchors = html.match(r)

// use only the first two
for (var i=0; i<2; i++) {

    // use only the stuff after the quotation mark to the end
    var dl = '' + /[^"]+$/.exec(anchors[i]);

    // if the location is a relative path, prepend the domain
    if (dl.substring(0,1) == '/') dl = /.+:\/\/[^\/]+/.exec(WSH.Arguments(0)) + dl;

    // target is path\filename
    var target=WSH.Arguments(1) + '\\' + /[^\/]+$/.exec(dl)

    // echo without a new line
    WSH.StdOut.Write('Saving ' + target + '... ');

    // fetch file and save it
    save(fetch(dl), target);

    WSH.Echo('Done.');
}

Update 2

Here's the same script with a few minor tweaks to have it also detect the architecture (32/64-bitness) of Windows, and only download one installer instead of two:

@if (@a==@b) @end /*

:: batch script portion

@echo off
setlocal

set "url=http://www.rarlab.com/download.htm"
set /p "savepath=Location to save? [%cd%] "

if "%savepath%"=="" set "savepath=%cd%"

cscript /nologo /e:jscript "%~f0" "%url%" "%savepath%"

goto :EOF

:: JScript portion */

// populate translation from locale identifier hex value to WinRAR language label
// http://msdn.microsoft.com/en-us/library/dd318693.aspx
var abbrev={}, a=function(arr,val){for(var i=0;i<arr.length;i++)abbrev[arr[i]]=val};
a(['1401','3c01','0c01','0801','2001','4001','2801','1c01','3801','2401'],'Arabic');
a(['042b'],'Armenian');
a(['082c','042c'],'Azerbaijani');
a(['0423'],'Belarusian');
a(['0402'],'Bulgarian');
a(['0403'],'Catalan');
a(['7c04'],'Chinese Traditional');
a(['0c04','1404','1004','0004'],'Chinese Simplified');
a(['101a'],'Croatian');
a(['0405'],'Czech');
a(['0406'],'Danish');
a(['0813','0413'],'Dutch');
a(['0425'],'Estonian');
a(['040b'],'Finnish');
a(['080c','0c0c','040c','140c','180c','100c'],'French');
a(['0437'],'Georgian');
a(['0c07','0407','1407','1007','0807'],'German');
a(['0408'],'Greek');
a(['040d'],'Hebrew');
a(['040e'],'Hungarian');
a(['0421'],'Indonesian');
a(['0410','0810'],'Italian');
a(['0411'],'Japanese');
a(['0412'],'Korean');
a(['0427'],'Lithuanian');
a(['042f'],'Macedonian');
a(['0414','0814'],'Norwegian');
a(['0429'],'Persian');
a(['0415'],'Polish');
a(['0816'],'Portuguese');
a(['0416'],'Portuguese Brazilian');
a(['0418'],'Romanian');
a(['0419'],'Russian');
a(['7c1a','1c1a','0c1a'],'Serbian Cyrillic');
a(['181a','081a'],'Serbian Latin');
a(['041b'],'Slovak');
a(['0424'],'Slovenian');
a(['2c0a','400a','340a','240a','140a','1c0a','300a','440a','100a','480a','080a','4c0a','180a','3c0a','280a','500a','0c0a','040a','540a','380a','200a'],'Spanish');
a(['081d','041d'],'Swedish');
a(['041e'],'Thai');
a(['041f'],'Turkish');
a(['0422'],'Ukranian');
a(['0843','0443'],'Uzbek');
a(['0803'],'Valencian');
a(['042a'],'Vietnamese');

function language() {
    var os = GetObject('winmgmts:').ExecQuery('select Locale from Win32_OperatingSystem');
    var locale = new Enumerator(os).item().Locale;

    // default to English if locale is not in abbrev{}
    return abbrev[locale.toLowerCase()] || 'English';
}

function fetch(url) {
    var xObj = new ActiveXObject("Microsoft.XMLHTTP");
    xObj.open("GET",url,true);
    xObj.setRequestHeader('User-Agent','XMLHTTP/1.0');
    xObj.send('');
    while (xObj.readyState != 4) WSH.Sleep(50);
    return(xObj);
}

function save(xObj, file) {
    var stream = new ActiveXObject("ADODB.Stream");
    with (stream) {
        type = 1; // binary
        open();
        write(xObj.responseBody);
        saveToFile(file, 2); // overwrite
        close();
    }
}

// fetch the initial web page
var x = fetch(WSH.Arguments(0));

// make HTML response all one line
var html = x.responseText.split(/\r?\n/).join('');

// get OS architecture (This method is much faster than the Win32_Processor.AddressWidth method)
var os = GetObject('winmgmts:').ExecQuery('select OSArchitecture from Win32_OperatingSystem');
var arch = /\d+/.exec(new Enumerator(os).item().OSArchitecture) * 1;

// get link matching *.exe where the link text contains system language and architecture
var r = new RegExp('<a\\s*href="[^"]+\\.exe(?=[^\\/]+' + language() + '[^<]+' + arch + '\\Wbit)');
var link = r.exec(html)

// use only the stuff after the quotation mark to the end
var dl = '' + /[^"]+$/.exec(link);

// if the location is a relative path, prepend the domain
if (dl.substring(0,1) == '/') dl = /.+:\/\/[^\/]+/.exec(WSH.Arguments(0)) + dl;

// target is path\filename
var target=WSH.Arguments(1) + '\\' + /[^\/]+$/.exec(dl)

// echo without a new line
WSH.StdOut.Write('Saving ' + target + '... ');

// fetch file and save it
save(fetch(dl), target);

WSH.Echo('Done.');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM