Что нового

[Сеть, интернет] Как скачать файл с родным именем?

Manonegro

Новичок
Сообщения
24
Репутация
0
Здравствуйте.

Как средствами AutoIt скачать файл с интернета с родным именем?
Например, ссылка http://cdburnerxp.se/downloadsetup.exe в любом менеджере закачек сохранит файл с именем cdbxp_setup_4.3.7.2420.exe

InetGet просит указывать имя для сохраняемого файла. А как его не менять?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Там перенаправление, можно это решить например так:

Код:
$sURL = "http://cdburnerxp.se/downloadsetup.exe"

$sHost = StringRegExpReplace($sURL, ".*://(.*?)/.*", "\1")
$sPage = StringRegExpReplace($sURL, ".*://.*?(/.*)", "\1")

$sResponse = _HTTPGetResponse($sHost, $sPage)
$sLocation = StringRegExpReplace($sResponse, "(?s).*Location: (.*?)[\r\n].*", "\1")

If @extended Then
	$sURL = $sLocation
EndIf

$sFileName = StringRegExpReplace($sURL, '^.*/', '')
InetGet($sURL, @ScriptDir & '\' & $sFileName)

Func _HTTPGetResponse($sHost, $sPage)
	TCPStartup()
	
	Local $sName_To_IP = TCPNameToIP($sHost)
	Local $iSocket = TCPConnect($sName_To_IP, 80)
	
	If $iSocket = -1 Then
		TCPShutdown()
		Return SetError(1, 0, "")
	EndIf
	
	Local $sCommand = "HEAD " & $sPage & " HTTP/1.1" & @CRLF
	
	$sCommand &= "Host: " & $sHost & @CRLF
	$sCommand &= "User-Agent: AutoIt/" & @AutoItVersion & " (Windows; U; Windows NT 5.1; en-US; rv:1.8.1)" & @CRLF
	$sCommand &= "Referer: " & $sHost & @CRLF
	$sCommand &= "Connection: close" & @CRLF & @CRLF
	
	Local $BytesSent = TCPSend($iSocket, $sCommand)
	
	If $BytesSent = 0 Then
		TCPShutdown()
		Return SetError(2, @error, 0)
	EndIf
	
	Local $sRecv = "", $sCurrentRecv
	
	While 1
		$sCurrentRecv = TCPRecv($iSocket, 16)
		If @error <> 0 Then ExitLoop
		If $sCurrentRecv <> "" Then $sRecv &= $sCurrentRecv
	WEnd
	
	TCPCloseSocket($iSocket)
	TCPShutdown()
	
	Return $sRecv
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Хороший пример!

P.S

Странно вот только, почему этого не делает InetGet()? Без второго параметра.
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Спасибо.
А действительно, как заставить работать InetGet() без второго параметра?
Код:
InetGet("http://cdburnerxp.se/downloadsetup.exe",  , 1, 1)
работать не хочет (выдает ошибку синтаксиса).
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Это и есть ошибка синтаксиса. Другое дело, если я пишу так:

Код:
InetGet("http://cdburnerxp.se/downloadsetup.exe")


В этом случае возвращает 0. В справке сказано, что второй параметр "filename" необязателен. И что из этого следует?
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Проверил скрипт Creator'а - работает, но дата модификации файла теряется (равна дате создания).

Кто-нибудь знает, как получить дату модификации файла с сервера?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Manonegro [?]
Проверил скрипт Creator'а - работает, но дата модификации файла теряется
А при чём тут мой пример, если я не ошибаюсь, InetGet качает в новый файл.

Нужна дата изменения, тогда так:

Код:
#include <Date.au3>

$sURL = "http://cdburnerxp.se/downloadsetup.exe"
$sFileDate = -1

$aSplit_URL = _HTTPURLSplit($sURL)
$sResponse = _HTTPGetResponse($aSplit_URL[0], $aSplit_URL[1])

If StringInStr($sResponse, 'Location:') Then
    $sURL = StringRegExpReplace($sResponse, "(?s).*Location: (.*?)[\r\n].*", "\1")
	
	$aSplit_URL = _HTTPURLSplit($sURL)
	$sResponse = _HTTPGetResponse($aSplit_URL[0], $aSplit_URL[1])
	
    $sFileDate = _HTTPGetDate(StringRegExpReplace($sResponse, "(?s).*Last-Modified: (.*?)[\r\n].*", "\1"), "%.4i%.2i%.2i%.2i%.2i%.2i")
EndIf

$sFileName = StringRegExpReplace($sURL, '^.*/', '')
InetGet($sURL, @ScriptDir & '\' & $sFileName)
FileSetTime(@ScriptDir & '\' & $sFileName, $sFileDate)

Func _HTTPGetResponse($sHost, $sPage)
    TCPStartup()
    
    Local $sName_To_IP = TCPNameToIP($sHost)
    Local $iSocket = TCPConnect($sName_To_IP, 80)
    
    If $iSocket = -1 Then
        TCPShutdown()
        Return SetError(1, 0, "")
    EndIf
    
    Local $sCommand = "HEAD " & $sPage & " HTTP/1.1" & @CRLF
    
    $sCommand &= "Host: " & $sHost & @CRLF
    $sCommand &= "User-Agent: AutoIt/" & @AutoItVersion & " (Windows; U; Windows NT 5.1; en-US; rv:1.8.1)" & @CRLF
    $sCommand &= "Referer: " & $sHost & @CRLF
    $sCommand &= "Connection: close" & @CRLF & @CRLF
    
    Local $BytesSent = TCPSend($iSocket, $sCommand)
    
    If $BytesSent = 0 Then
        TCPShutdown()
        Return SetError(2, @error, 0)
    EndIf
    
    Local $sRecv = "", $sCurrentRecv
    
    While 1
        $sCurrentRecv = TCPRecv($iSocket, 16)
        If @error <> 0 Then ExitLoop
        If $sCurrentRecv <> "" Then $sRecv &= $sCurrentRecv
    WEnd
    
    TCPCloseSocket($iSocket)
    TCPShutdown()
    
    Return $sRecv
EndFunc

Func _HTTPURLSplit($sURL)
	Local $aRet[2] = [StringRegExpReplace($sURL, ".*://(.*?)/.*", "\1"), StringRegExpReplace($sURL, ".*://.*?(/.*)", "\1")]
	Return $aRet
EndFunc

Func _HTTPGetDate($sDate, $sFormat = "%.4i/%.2i/%.2i %.2i:%.2i:%.2i")
	$aSplit = StringRegExp($sDate, "(?i)\w+, (\d+) (\w+) (\d{4}) (\d+):(\d+):(\d)", 3)
	
	$iDay = $aSplit[0]
	$iMonth = $aSplit[1]
	$iYear = $aSplit[2]
	$iHour = $aSplit[3]
	$iMin = $aSplit[4]
	$iSec = $aSplit[5]
	
	For $i = 1 To 12
		If _DateToMonth($i, 1) = $aSplit[1] Then
			$iMonth = $i
			ExitLoop
		EndIf
	Next
	
	Return StringFormat($sFormat, $iYear, $iMonth, $iDay, $iHour, $iMin, $iSec)
EndFunc
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Большое спасибо. Можно считать, что тема решена, хоть и через огромную "пятую точку". ;D
А как бы было замечательно всё это делать через стандартный InetGet...
 
Верх