如何在PowerShell中从网页下载一个完整的文件夹和子文件夹

9

我可以使用以下方法从网络下载单个文件:

$wc = New-Object System.Net.WebClient
$wc.DownloadFile("http://blah/root/somefile.ext", "C:\Downloads\www\blah\root\somefile.ext")

但是如何下载所有文件,包括子文件夹?类似以下的方式会很好...
$wc.DownloadFile("http://blah/root/", "C:\Downloads\www\blah\root\")

在IE中,根目录本身会显示为一个目录列表,类似于:

[To Parent Directory]
                01 July 2012    09:00       1234 somefile.ext
                01 July 2012    09:01       1234 someotherfile.ext

作为额外的信息,我如何仅仅下载根文件夹中的文件,忽略子文件夹?

我认为你的Web服务器不支持这个。只有单个文件的URI可以使用GET。所以你的解决方案需要分成两部分:1)下载目录列表作为HTML并解析文件URL;2)下载每个文件。 - Andy Arismendi
2个回答

8

根据Andy的建议(当然也有很多谷歌的帮助),这是我想出来的:

####################################################################################################
# This function copies a folder (and optionally, its subfolders)
#
# When copying subfolders it calls itself recursively
#
# Requires WebClient object $webClient defined, e.g. $webClient = New-Object System.Net.WebClient
#
# Parameters:
#   $source      - The url of folder to copy, with trailing /, e.g. http://website/folder/structure/
#   $destination - The folder to copy $source to, with trailing \ e.g. D:\CopyOfStructure\
#   $recursive   - True if subfolders of $source are also to be copied or False to ignore subfolders
#   Return       - None
####################################################################################################
Function Copy-Folder([string]$source, [string]$destination, [bool]$recursive) {
    if (!$(Test-Path($destination))) {
        New-Item $destination -type directory -Force
    }

    # Get the file list from the web page
    $webString = $webClient.DownloadString($source)
    $lines = [Regex]::Split($webString, "<br>")
    # Parse each line, looking for files and folders
    foreach ($line in $lines) {
        if ($line.ToUpper().Contains("HREF")) {
            # File or Folder
            if (!$line.ToUpper().Contains("[TO PARENT DIRECTORY]")) {
                # Not Parent Folder entry
                $items =[Regex]::Split($line, """")
                $items = [Regex]::Split($items[2], "(>|<)")
                $item = $items[2]
                if ($line.ToLower().Contains("&lt;dir&gt")) {
                    # Folder
                    if ($recursive) {
                        # Subfolder copy required
                        Copy-Folder "$source$item/" "$destination$item/" $recursive
                    } else {
                        # Subfolder copy not required
                    }
                } else {
                    # File
                    $webClient.DownloadFile("$source$item", "$destination$item")
                }
            }
        }
    }
}

当然不能保证一定成功,但它对我感兴趣的网站有效。


似乎这会节省很多时间。您能否添加一个使用此函数的示例? - Shameel Mohamed

2

以下是对@FrinkTheBrave回答的补充,介绍如何运行他的脚本:

  • 将脚本保存到文件中,例如“DLfilesFromSite.ps1”

  • 以管理员身份运行PowerShell

  • cd到包含脚本的文件夹:

    cd c:\scripts

  • 导入脚本:

    Import-Module .\DLfilesFromSite.ps1

  • 初始化webclient:

    $webClient = New-Object System.Net.WebClient

  • 设置带有变音符号的文件的编码方式:

    $webClient.Encoding = [System.Text.Encoding]::UTF8

  • 使用参数调用函数:

    Copy-Folder "https://www.example.cz/source/folder/" "C:\destination\folder" $True

我在这篇文章中学到了很多关于powershell脚本和传递参数的知识。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接