首页 新闻 会员 周边 捐助

C#使用HttpWebRequest读取网站内容遭遇503错误?

0
[待解决问题]

本人多年编程小白,天生编程白痴体质。大家莫见笑。
自己用C#写了一段代码,使用HttpWebRequest,通过SOHU的API接口获取指定股票的交易信息。
该段代码一直运行正常。最近开始报错。
详细信息如下:
System.Net.WebException
HResult=0x80131509
Message=远程服务器返回错误: (503) 服务器不可用。

通过在浏览器地址栏直接输入查询URL的方式可以正常返回数据。

只是通过代码查询的时候会报上面的错误。

可以判定,问题出在代码中。由于以前是正常运行的,应该是网站接口进行了某种升级。
这种情况该如何DEBUG呢?

问题补充:

一直在DEBUG,找不到原因。
发现一个现象,按F11逐语句调试,就可以正常运行。
按F10逐过程调试,就会报503错误。
太奇怪了。

happygogogo的主页 happygogogo | 菜鸟二级 | 园豆:202
提问于:2024-09-20 15:40
< >
分享
所有回答(4)
0

您好!遇到这种问题,可以按照以下步骤进行DEBUG:

  1. 确认错误是否由于网站接口升级引起的:您已经通过在浏览器地址栏直接输入查询URL的方式能够正常返回数据,这表明网站接口可能没有问题。但是仍然可以尝试通过直接访问API接口来确认是否能够正常获取数据。
  2. 检查代码中的错误:可以检查一下代码中是否存在错误。检查您的HttpWebRequest相关代码是否有任何变化或错误,例如是否有缺失的参数、错误的URL等。确保您的代码没有问题,如果有需要,可以参考文档或者检查第三方库的最新用法。
  3. 模拟请求:检查您的代码是否正确设置了请求头、请求方法、请求参数等。您可以尝试使用其他工具(如Postman)来模拟相同的请求,以确认是否能够成功获取数据。
  4. 网络连接问题:由于报错信息中提到了"服务器不可用",这也可能是由网络连接问题引起的。您可以检查您的网络连接是否正常,并确保您的代码可以正常访问其他网站。
  5. 错误日志或其他记录:如果您能够获得更多的错误日志或者其他记录,可以进一步分析这些信息以获得更多的线索。
    如果您尝试了以上步骤后仍然无法解决问题,您可以考虑联系SOHU的技术支持,他们可能能够提供更好的帮助和解决方案。希望这些信息对您有所帮助!如有其他问题,请随时提问。
Technologyforgood | 园豆:7484 (大侠五级) | 2024-09-23 08:06
0

对比你的代码请求 和 通过浏览器访问请求 有什么区别

  • url
  • 请求头
  • 请求体
复制粘贴机器人 | 园豆:720 (小虾三级) | 2024-09-23 08:43

我用Fiddler对比了一下,确实有一个区别:
浏览器访问 Host: q.stock.sohu.com:443
代码访问 Host: q.stock.sohu.com

代码的host没有443端口,不知道代码哪里设置有问题。

支持(0) 反对(0) happygogogo | 园豆:202 (菜鸟二级) | 2024-09-23 10:31

@happygogogo: 443是https ,没有443默认是80 http

支持(0) 反对(0) 复制粘贴机器人 | 园豆:720 (小虾三级) | 2024-09-23 10:37
0

帮你gpt一下:
出现这种 (503) 服务器不可用 错误时,虽然通过浏览器直接访问API可以正常返回数据,但代码访问时报错,说明可能存在以下几种情况:

可能原因

  1. User-Agent 相关问题:网站可能对非浏览器的请求进行了限制,部分API会验证请求的 User-Agent,阻止来自自动脚本或程序的请求。

  2. 请求频率限制:某些API会对频繁的请求进行限制,503 错误可能是由于你在短时间内发起了过多的请求。

  3. HTTP/HTTPS 协议不匹配:部分网站可能升级了协议,要求使用 HTTPS 请求,而你的代码可能仍在使用 HTTP。

  4. 服务器端限流:API服务器可能对某些请求或IP地址做了限流,导致你的程序访问受阻。

  5. 代理或防火墙问题:某些环境中使用代理或防火墙的情况下,可能会拦截你的请求。

Debug 和解决方法

  1. 检查 User-Agent
    很多时候,API会要求请求头中的 User-Agent 模拟为浏览器的形式。你可以在代码中添加或修改 User-Agent,模拟浏览器请求。

    var request = (HttpWebRequest)WebRequest.Create("http://api.sohu.com/stock");
    request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36";
    
  2. 增加延时:如果是请求频率过高导致的503错误,尝试在多个请求之间添加延时。

    System.Threading.Thread.Sleep(1000); // 每次请求之间延迟1秒
    
  3. 检查 HTTP/HTTPS:确保请求URL使用正确的协议。如果你以前用的是 http,可以尝试改为 https,以防服务器升级导致的协议问题。

  4. 抓包分析:可以使用抓包工具(如Fiddler或Wireshark)来比较浏览器与代码请求的差异。查看哪些请求头字段在浏览器中存在而在代码中没有设置。

  5. 捕获更多异常信息:对代码中的异常进行详细捕获,记录更多信息以便调试。

    try
    {
        // 发送请求代码
    }
    catch (WebException ex)
    {
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        {
            Console.WriteLine($"Status Code: {response.StatusCode}");
            Console.WriteLine($"Status Description: {response.StatusDescription}");
        }
        Console.WriteLine(ex.ToString());
    }
    

例子代码

下面是一个可能的修复示例:

using System;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        try
        {
            var url = "http://api.sohu.com/stock";
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36";
            request.Timeout = 10000; // 设置超时时间
            request.KeepAlive = false; // 禁用 Keep-Alive

            using (var response = (HttpWebResponse)request.GetResponse())
            using (var stream = response.GetResponseStream())
            using (var reader = new StreamReader(stream))
            {
                var responseText = reader.ReadToEnd();
                Console.WriteLine(responseText);
            }
        }
        catch (WebException ex)
        {
            Console.WriteLine("WebException caught: " + ex.Message);
            if (ex.Response != null)
            {
                using (var errorResponse = (HttpWebResponse)ex.Response)
                {
                    Console.WriteLine("HTTP Status Code: " + (int)errorResponse.StatusCode);
                    using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                    {
                        string errorText = reader.ReadToEnd();
                        Console.WriteLine("Error response: " + errorText);
                    }
                }
            }
        }
    }
}

小结

通过调整 User-Agent、限制请求频率、切换协议等方式,通常可以解决此类API请求问题。抓包分析则是更深一步调试的有力工具。

七七七七七子 | 园豆:446 (菜鸟二级) | 2024-09-23 09:50

我用Fiddler对比了一下,确实有一个区别:
浏览器访问 Host: q.stock.sohu.com:443
代码访问 Host: q.stock.sohu.com

代码的host没有443端口,不知道代码哪里设置有问题。
我推测可能是API原来是可以接受http请求的,后来服务器升级为只接受https请求了。
我的代码应该是通过HTTP查询的,虽然我代码里的请求地址是https开头的,但是因为某种原因,实际执行时是通过http请求。
我对HttpWebRequest查询https接口操作不熟悉。有没有示例代码啊?

支持(0) 反对(0) happygogogo | 园豆:202 (菜鸟二级) | 2024-09-23 10:39
0

增加容错处理机制:

请求偶尔会有:503错误!

 但是不多;所以增加错误重试机制就行了;

 

  private static async Task GetStock()
    {
        var url = "http://q.stock.sohu.com/hisHq?code=cn_300228&start=20130930&end=20130931&stat=1&order=D&period=d&callback=&rt=jsonp";
        using var client = new HttpClient();

        var tryTimes = 10; //失败,重试次数;
        while (tryTimes > 0)
        {
            try
            {
                var result = await client.GetStringAsync(url);
                tryTimes = 10;

                Console.WriteLine(result);
                break;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Thread.Sleep(1000);
                tryTimes--;
                continue;
            }
        }
    }
张朋举 | 园豆:1936 (小虾三级) | 2024-10-07 16:30
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册