首页 > 编程语言 >C# 爬虫 HttpClient 之 https 踩坑记录

C# 爬虫 HttpClient 之 https 踩坑记录

时间:2023-04-20 21:24:07浏览次数:38  
标签:return C# client https var new response HttpClient

背景

有一个网页(https),请求返回是一串json,可通过模拟浏览器获取,也可以通过api请求获取,其中通过C#的httpclient的Get发起请求,会出现不定时的返回结果乱码

请求代码

[HttpPost(Name = "GetTestNoParams")]
        public async Task<string> GetTestNoParams(string url)
        {
            var ret = string.Empty;
            try
            {
                var httpClientHandler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true,
                };

                var client = new HttpClient(httpClientHandler);
                client.Timeout = new TimeSpan(0, 0, 5);
                client.DefaultRequestHeaders.Add("Host", "www.southernfund.com");
                client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br");
                var response = await client.GetAsync(new Uri("url"));
                if (response.IsSuccessStatusCode)
                {
                    return await response.Content.ReadAsStringAsync();
                }
                else
                    return $"请求失败:{response.RequestMessage}";
            }
            catch (Exception ex)
            {

                return ex.Message;
            }
        }

首先乱码排查

通过浏览器直接访问,发现该网页一段时间返回结果会进行压缩,一段时间结果直接返回,直接是json串 【Content-Encoding: gzip 可以判断内容进行了gzip压缩】

此时代码运行返回乱码

乱码解决

知道内容进行了gzip压缩,那我们就对内容进行GZIP解压缩,代码如下

[HttpPost(Name = "GetTestNoParams")]
        public async Task<string> GetTestNoParams(string url)
        {
            var ret = string.Empty;
            try
            {
                var httpClientHandler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true,
                };

                var client = new HttpClient(httpClientHandler);
                client.Timeout = new TimeSpan(0, 0, 5);
                client.DefaultRequestHeaders.Add("Host", "www.southernfund.com");
                client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br");
                var response = await client.GetAsync(new Uri("url"));
                if (response.IsSuccessStatusCode)
                {
                    var stream = await response.Content.ReadAsStreamAsync();
                    var bts = Decompress(stream);
                    return Encoding.UTF8.GetString(bts);
                    //return await response.Content.ReadAsStringAsync();
                }
                else
                    return $"请求失败:{response.RequestMessage}";
            }
            catch (Exception ex)
            {

                return ex.Message;
            }
        }

 public static byte[] Decompress(Stream stream)
        {
            var gzipStream = new GZipStream(stream, CompressionMode.Decompress);
            var mmStream = new MemoryStream();
            byte[] block = new byte[1024];
            while (true)
            {
                int byteRead = gzipStream.Read(block, 0, block.Length);
                if (byteRead <= 0)
                    break;
                else
                    mmStream.Write(block, 0, byteRead);
            }
            mmStream.Close();
            return mmStream.ToArray();
        }

返回结果正常

bug

上述看似问题处理 但是这里面有个bug ,就是C#通过httpclient发起get请求的response的headers中不包含 Content-Encoding: gzip这个头信息,程序无法自动判断解压缩,上述代码也是强解压,当对方服务器切换返回非压缩的内容时,上述代码仍旧无法获取正常内容

C#通过httpclient发起get请求的response的headers

不过楼主发现通过python是可以获取到的

紧急的就用python做 后续期望C#能找到解决办法

标签:return,C#,client,https,var,new,response,HttpClient
From: https://www.cnblogs.com/Alicia-meng/p/17338389.html

相关文章

  • Junit启动测试mybatis xml文件BindingException: Invalid bound statement问题
    背景:1、正常启动,xml文件放在java目录和resource目录下均正常2、junit启动,xml文件放在resource目录下正常,放在java目录下报BindingException错误mapperlocation绑定地址为:"classpath:com/a/b/**/*.xml" 原因就在于绑定的地址有问题。 junit生成的test-classes下的测......
  • SpringBoot + WebFlux + Spring Security ,SecurityContextHolder.getContext().getA
    解决方案直接在Controller接口方法参数中写入org.springframework.security.core.Authentication,如下:@GetMapping(path="/test")publicMono<Response<?,?>>test(Authenticationauthentication){returnMono.just(ResponseUtil.success(authentica......
  • C++ 结构体对齐
    C++结构体对齐引言数据结构对齐是数据在计算机内存中排列和访问的方式。它由三个独立但相关的问题组成:数据对齐、数据结构填充和打包。现代计算机硬件中的CPU在数据自然对齐时最有效地执行内存读取和写入,这通常意味着数据的内存地址是数据大小的倍数。例如,在32位架构中,如果......
  • idea配置tomcat
    ​许多小伙伴原来都使用的eclipse进行Java代码的编写,在改用IDEA以后不会进行原来的一些配置,今天我来交给大家如何在IDEA上进行tomcat的配置1.添加tomcat按照上述图片所述顺序对tomcat进行添加.2.对tomcat进行配置在完成这些简单的配置以后点击OK,这时页面上出现了t......
  • #yyds干货盘点#match 语句
    最简单的形式是将一个目标值与一个或多个字面值进行比较:defhttp_error(status):matchstatus:case400:return"Badrequest"case404:return"Notfound"case418:return"I'mateapot"......
  • JDBC--API--Connection
       ......
  • 学习JavaScript
    操作步骤开通语音识别服务在调用语音识别相关接口前,您需要进入 语音识别控制台,进行实名认证和人脸认证,认证完成后,阅读《用户协议》后勾选“我已阅读并同意《用户协议》”,然后单击【立即开通】,即可一键开通录音文件识别、实时语音识别、一句话识别、录音文件识别极速版、语......
  • MFC-添加资源
     添加图片资源           ......
  • 微信小程序使用canvas2d实现拼图游戏
    根据周文洁微信小程序开发实战编写,但是微信更新了canvas接口,按照书上写的已经不能使用了。目录 改进后如下:app.wxss:1.container{2height:100vh;3color:#E64340;4font-weight:bold;5display:flex;6flex-direction:column;7align-i......
  • eclipse字体更改
    代码编辑界面默认颜色为白色。对于长期使用电脑编程的人来说,白色很刺激我们的眼睛,所以改变workspace的背景色,可以使眼睛舒服一些。设置方法如下:1、打开window/Preference,弹出Preference面板2、展开General标签,选中Editors选项,展开。3、选中TextEditors,右边出现TestEdito......