调用SEC EDGAR API时HttpClient/WebClient返回404协议错误如何解决?
解决方案
核心错误为手动配置的Host请求头与接口实际域名不匹配:你要请求的接口域名是data.sec.gov,但所有请求代码中都强制指定Host为www.sec.gov,服务端无法正确匹配路由,因此返回404错误。
修正步骤
- 删除所有请求代码中手动设置
Host头的逻辑,由框架自动根据请求URL生成正确值 - 程序启动时全局配置TLS版本为TLS 1.2,满足SEC的HTTPS访问要求
- 开启响应自动解压缩,适配gzip/deflate编码的返回内容
- 替换
User-Agent值为你真实的应用名称+联系邮箱,符合SEC的开发者调用规则
修正后完整可用代码(基于官方推荐的HttpClient)
首先在程序入口(如窗体Load事件或Sub Main)添加TLS配置:
' 程序启动时执行一次即可 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
修正后的请求模块代码:
Imports System.IO Imports System.Net Imports System.Net.Http Imports System.Net.Http.Headers Public Module SECJSON ' 测试接口地址 Public sourceUrl As String = "https://data.sec.gov/api/xbrl/frames/us-gaap/AccountsPayableCurrent/USD/CY2019Q1I.json" ' 替换为你自己的应用名+真实邮箱,符合SEC要求 Public ua As String = "My Edgar Reader Admin@youremail.com" Public accept As String = "application/json" ' HttpClient建议静态复用,不要每次请求新建 Private ReadOnly _httpClient As HttpClient = New HttpClient(New HttpClientHandler() With { .AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate }) Public Sub RunAttempts() ' 异步调用建议用Await,此处简化测试直接用Wait() Fetch2(sourceUrl).Wait() End Sub Public Async Function Fetch2(page As String) As Task(Of String) Dim request As New HttpRequestMessage(HttpMethod.Get, New Uri(page)) ' 配置请求头 request.Headers.Accept.Add(New MediaTypeWithQualityHeaderValue(accept)) request.Headers.UserAgent.ParseAdd(ua) Using response As HttpResponseMessage = Await _httpClient.SendAsync(request) ' 确保请求成功 response.EnsureSuccessStatusCode() Dim result As String = Await response.Content.ReadAsStringAsync() Debug.WriteLine("HttpClient请求结果:") Debug.WriteLine(result) Return result End Using End Function End Module
注意事项
- App.config中已配置的
useUnsafeHeaderParsing可以保留,适配SEC服务端可能返回的非标准响应头 - 不要频繁发起请求,SEC对调用频率有限制,要求每秒请求数不超过10次
- 如果需要大量拉取数据,建议优先使用SEC的批量归档文件,减少接口调用压力
内容的提问来源于stack exchange,提问作者Berries
相关产品推荐
相关产品推荐

