如何用PowerShell获取URL自动触发下载的XLS文件并转为CSV?
解决PowerShell下载XLS文件仅得到HTML的问题
问题原因
浏览器能正常下载但PowerShell命令不行,通常是因为:
- 请求缺少浏览器自带的HTTP头(比如
User-Agent、Referer),网站拒绝返回文件 - 链接是触发下载的跳转页,而非直接文件URL,浏览器会自动处理后续请求
- 网站需要会话Cookie验证,PowerShell默认不保持会话
解决方案
1. 模拟浏览器请求头与会话
复制浏览器的请求头(比如Chrome按F12→网络→选中下载请求→查看请求头),添加到PowerShell请求中,并使用会话保持Cookie:
$downloadUrl = "你的邮件中获取的下载链接" $outputXls = "C:\Downloads\file.xls" # 替换为你浏览器的User-Agent,可从F12网络请求中复制 $requestHeaders = @{ "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" "Referer" = "如果下载链接有来源页,填对应URL" } # 创建会话对象保持Cookie $webSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession # 发起请求并保存文件 Invoke-WebRequest -Uri $downloadUrl -WebSession $webSession -Headers $requestHeaders -OutFile $outputXls
2. 获取实际文件下载URL(如果上述方法无效)
有些链接是跳转页,点击后才生成真实文件URL,需通过浏览器抓包获取:
- 打开浏览器F12→切换到「网络」标签
- 点击邮件中的下载链接,找到类型为
application/vnd.ms-excel的请求 - 复制该请求的URL,直接用这个URL在PowerShell中下载
3. 将XLS转换为CSV
方法一:使用Excel COM对象(需安装Microsoft Excel)
$xlsPath = "C:\Downloads\file.xls" $csvPath = "C:\Downloads\file.csv" $excelApp = New-Object -ComObject Excel.Application $excelApp.Visible = $false # 后台运行不显示Excel窗口 $workbook = $excelApp.Workbooks.Open($xlsPath) $worksheet = $workbook.Worksheets.Item(1) # 取第一个工作表 # 保存为CSV格式(6是CSV对应的枚举值) $worksheet.SaveAs($csvPath, 6) # 清理资源避免Excel进程残留 $workbook.Close() $excelApp.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($worksheet) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelApp) | Out-Null [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers()
方法二:使用ImportExcel模块(无需Excel)
先安装模块(需管理员权限或允许当前用户安装):
Install-Module -Name ImportExcel -Scope CurrentUser -Force
然后转换:
Import-Excel -Path $xlsPath | Export-Csv -Path $csvPath -NoTypeInformation
特殊情况:XLS是伪装的HTML表格
如果下载的文件本质是HTML(后缀名被改为.xls),可直接提取表格内容转CSV:
$response = Invoke-WebRequest -Uri $downloadUrl -WebSession $webSession -Headers $requestHeaders $table = $response.ParsedHtml.getElementsByTagName("table")[0] $csvLines = @() foreach ($row in $table.getElementsByTagName("tr")) { $cells = $row.getElementsByTagName("td") $csvLine = ($cells | ForEach-Object { $_.innerText -replace ",",";" }) -join "," $csvLines += $csvLine } $csvLines | Out-File $csvPath -Encoding UTF8
内容的提问来源于stack exchange,提问作者Andrew Draper
相关产品推荐
相关产品推荐

