【问题标题】:Using wildcards to download a file with Invoke-WebRequest使用通配符通过 Invoke-WebRequest 下载文件
【发布时间】:2016-01-27 13:46:39
【问题描述】:

我有一个 6 位数字的网址,每天都在变化。

示例网站https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/ea_csv_160126.csv

这是变化的部分:160126

我不知道正确的语法,但作为一种伪代码:

$url = "https://www.ecb.europa.eu/paym/coll/assets
/html/dla/ea_MID/ea_csv_" + [0-9][0-9][0-9][0-9][0-9][0-9]+ ".csv"

我该如何写这个字符串?

为了回答 cmets,我使用它来将该文件下载到一个文件夹中,如下所示:

"https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/ea_csv_" + [0-9]+[0-9]+[0-9]+[0-9]+[0-9]+[0-9] +".csv"
$output = "C:\MyFolder\SomeSubFolder\ScriptDownload"
$start_time = Get-Date

Invoke-WebRequest -Uri $url -OutFile $output  
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"  

【问题讨论】:

  • 你如何使用这个字符串?这将决定我们如何称呼它
  • @Matt Hi Matt,请看我的编辑
  • @CM2K 所以你在任何时候都不知道文件名是什么?只是那有 100000 个可能的不同文件名?
  • 我知道文件名应该是一个日期,通常是 currentDate - 1 天,如果今天是星期一,则返回星期五。但我根本不想使用这个逻辑。我只是想在.csv 之前使用带有6 位数字占位符的网站。该文件将在那里,并认为它会工作
  • 我问是因为我认为这是你的想法。你期望它如何工作?检查 1000 个网站,直到它获得成功?大致基于今天比猜测-Uri 不支持哪个要好得多。

标签: powershell powershell-3.0 powershell-ise


【解决方案1】:

您可以通过下载页面或使用 get-ElementById 等来解析下载页面的文件名。 我假设,这是原始下载page

这是您的下载网址:

    $Url = "https://www.ecb.europa.eu/paym/coll/assets/html/list-MID.en.html"
$page = Invoke-WebRequest -Uri $Url
$a = ($page.ParsedHtml.getElementsByTagName('table') | ? {$_.classname -eq 'ecb-contentTable'}).textContent
$filename =  $a.Substring($a.IndexOf('ea_csv_'), 17)
$DLURL =  "https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/" + $filename

给予:

$DLURL
https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/ea_csv_160126.csv

用你的来完成

$output = "C:\MyFolder\SomeSubFolder\ScriptDownload\" + $filename
Invoke-WebRequest -Uri $DLURL -OutFile $Output

完成了。

【讨论】:

  • 对,就是下载页面。你会怎么做?对此很陌生
  • 谢谢马丁,但这里有与马特的解决方案相同的问题,将复制粘贴:“不是名称中包含更新的文件。我试图避免像瘟疫一样的文件。上面那个没压缩过的。其他看起来不错,很快就测试了"
  • 将其从$DLURL = "https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/" + $a.Substring($a.IndexOf('ea_csv_update_'), 24)更正为$DLURL = "https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/" + $a.Substring($a.IndexOf('ea_csv_'), 17)
  • 所以,像这样吗? $Url = "https://www.ecb.europa.eu/paym/coll/assets/html/list-MID.en.html" $page = Invoke-WebRequest -Uri $Url $a = ($page.ParsedHtml.getElementsByTagName('table') | ? {$_.classname -eq 'ecb-contentTable'}).textContent $DLURL = "https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/" + $a.Substring($a.IndexOf $output = "C:\MyFolder\SomeSubFolder\ScriptDownload" Invoke-WebRequest -Uri $DLURL -OutFile $Output 不起作用 :(
  • 只需使用我原始答案的第一部分和第三部分。您的 $Output 缺少像 $output = "C:\MyFolder\SomeSubFolder\ScriptDownload\download.csv" 这样的文件名(编辑了我的原始答案以反映更改。)
【解决方案2】:

您所要求的无法完成。但是,有更好、更可靠的方法来获得您正在寻找的相同结果。

我和Martin 在一起。我还找到了他做的下载页面。更好的方法是获取链接。现在这可能不是获取信息的最佳方式,但它是朝着正确方向的开始。

请注意,这非常慢。主要是因为Invoke-WebRequest

$start_time = Get-Date
$output = "C:\MyFolder\SomeSubFolder\ScriptDownload"
# Browse to the page hosting the csv file.
$request = Invoke-WebRequest "https://www.ecb.europa.eu/paym/coll/assets/html/list-MID.en.html"
# Locate the uncompressed CSV file name from the page
$filename = $request.ParsedHtml.getElementsByTagName("a") | Where-Object{$_.nameProp -match "^ea_csv_\d{6}\.csv$"} | Select -ExpandProperty nameProp
$fileurl = "https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/$filename"

# Get the file the is hosted today.
Invoke-WebRequest -Uri $fileurl -OutFile "$output\$filename" 
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"  

我们找到正确文件名的方法是使用^ea_csv_\d{6}\.csv$,它与恰好是“ea_csv_[6 位].csv”的名称相匹配。

【讨论】:

  • 不错的解决方案,我喜欢{$_.nameProp -like "ea_csv_update*csv"} 部分
  • 不是名称中带有update 的文件。我试图避免像瘟疫一样的文件。它上面的未压缩的。否则看起来不错,将很快测试
  • 将这部分"ea_csv_update*csv" 更改为"ea_csv_*csv" 但整个事情将整个页面的html代码作为错误返回
  • 啊。 ok 这样做会返回多个链接。我可以使用正则表达式来完成这项工作以获得您想要的。
  • 返回:Invoke-WebRequest : The process cannot access the file 'C:\MyFolder\SomeSubFolder\ScriptDownload' because it is being used by another process. At line:10 char:1 + Invoke-WebRequest -Uri $fileurl -OutFile $output + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], IOException + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand 我没有打开或使用它。我需要一些覆盖吗?
【解决方案3】:

这 6 位数字是编码为 YYMMDD 的日期,对吗?如果是这样,您可以使用以下命令生成当天的 URL:

$currentDay = $(get-date).ToString("yyMMdd")
$url = "https://www.ecb.europa.eu/paym/coll/assets/html/dla/ea_MID/ea_csv_$currentDay.csv"

【讨论】:

  • 几乎正确。数据并不总是每天更新,然后是周末。因此,我宁愿使用带有该 URL + 任何 6 位数字 + .csv 的东西。此外,对于今天,您没有今天的数据。你有昨天的数据,你可以猜到星期一会发生什么
  • @CM2K 在脚本中使用这样的解决方案如何,安排它使用任务调度程序运行,然后只在工作日运行?
  • 我没有任务调度程序的访问权限。我想将它合并到我在 SSIS 中的项目中,我必须每天运行一次。但那是另一回事了。我不是在寻找任何复杂的解决方案。只是如何通过那该死的 [0-9] 6 次
  • @CM2K 当然,那会很不错,但那是不可能的——这不是 HTTP 的工作原理
  • 您可以尝试获取日期的工作日信息。基本上,您在周二至周五使用 (get-date).add-days(-1)。星期一你将使用 (get-date).add-days(-3)。
猜你喜欢
  • 1970-01-01
  • 2021-10-17
  • 2023-01-21
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
相关资源
最近更新 更多