PowerShell如何读取文本文件内链接爬取网页CVE信息
故障原因
你的脚本报空值错误是多个逻辑问题共同导致的:
- 循环对象配置错误:
ForEach ($URI in $Path)语句中遍历的$Path是本地文本文件的路径字符串,不是提取到的网址列表,循环时会直接把本地文件路径当URL发起请求,必然触发异常。 - 网址提取逻辑不完整:筛选出带
Name关键词的行后,没有做字符串切割,拿到的是带Name :前缀的整行文本,不是合法可访问的URL格式。 - 元素匹配规则失效:你写的a标签href匹配规则是完全等于固定字符串
http://web.nvd.nist.gov/view/vuln/detail?vulnId,但实际页面上的CVE链接是带具体CVE编号后缀的,永远匹配不到目标元素,自然返回null值。 - 解析方法兼容性问题:使用
-UseBasicParsing参数发起请求时,非IE环境的PowerShell不会为返回结果填充ParsedHtml属性,直接调用该属性的方法会触发空值错误。 - 输出逻辑缺陷:每次循环都会覆盖输出文件的已有内容,最终只会保留最后一个页面的爬取结果,且未指定编码容易出现乱码。
修正后代码
# 配置路径 $linkFilePath = "C:\Users\Windows\Downloads\Links.txt" $outputFilePath = "C:\Users\Windows\Downloads\CVEList.txt" # 从文本文件提取所有目标URL,自动去重 $uriList = Get-Content $linkFilePath | Where-Object { $_ -match '(Name|Address)\s*:\s*(https?://.+)' } | ForEach-Object { $matches[2].Trim() } | Select-Object -Unique $cveResult = [System.Collections.Generic.List[string]]::new() foreach ($uri in $uriList) { try { Write-Host "正在处理链接: $uri" $resp = Invoke-WebRequest -Uri $uri -UseBasicParsing -ErrorAction Stop # 用正则直接匹配页面中所有标准格式的CVE编号,兼容性更强 $matches = [regex]::Matches($resp.Content, 'CVE-\d{4}-\d{4,}') if ($matches.Count -gt 0) { $matches | ForEach-Object { $cveResult.Add($_.Value) } } } catch { Write-Warning "链接 $uri 处理失败: $($_.Exception.Message)" } } # 结果去重后写入文件,指定UTF8编码避免乱码 $cveResult | Select-Object -Unique | Out-File $outputFilePath -Encoding utf8 Write-Host "处理完成,CVE列表已保存至: $outputFilePath"
关键调整说明
- 修正了循环遍历对象,改为遍历从文本中正则提取、去重后的真实URL列表
- 优化URL提取逻辑,自动捕获
Name、Address字段后的真实网址,剔除多余空格和前缀文本,同时自动去重避免重复爬取相同链接 - 放弃兼容性差的DOM解析方式,直接通过正则匹配响应内容中的CVE编号,不受页面链接格式变动、COM组件依赖的影响,从根源避免空值错误
- 增加异常捕获逻辑,单个链接爬取失败不会中断整个脚本运行,同时输出错误信息方便排查
- 优化输出逻辑,所有链接爬取完成后统一去重写入文件,不会覆盖历史结果,指定UTF8编码解决乱码问题
- 增加运行状态提示,可实时查看爬取进度
内容的提问来源于stack exchange,提问作者soccerrat
相关产品推荐
相关产品推荐

