码迷,mamicode.com
首页 > Windows程序 > 详细

C#爬页面总结

时间:2016-05-05 22:04:05      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:

错误的思路是这样的:发送一个访问页面的请求过去,得到一个html页面,然后我要的数据全都在这上面。后来发现不是这样的,也猜到可能是页面加载之后还有js代码的ajax的异步加载,那么问题来了?我是不是要等到这些ajax请求结束之后,我才能拿到数据呢?我怎么判断有没有结束?我要等多久合适呢?嗯,仔细向下,还有个问题是,发送的post请求过去,又没有浏览器渲染,谁去执行这些js代码呢?
 
实际上是这样的:发送一个访问页面的请求过去,上面可能有我要的数据,也可能没有,如果没有,那就看看是不是要发另外的请求。

1、相关工具和技巧

1.1 Chrome浏览器

 打开浏览器,按F12进入调式状态,例如打开www.cnblogs.com
  技术分享
 

1.2 fiddler工具

用fiddler工具查看原始的请求数据,一般都会有一定的编码格式。用Chrome工具可能看不出来编码格式。
技术分享
 

1.3 编码解码的工具

这些就不列举了,可以找在线工具。比如下面这个的:
附js编码与.net编码:
1.window.escape()与HttpUtility.UrlEncodeUnicode()编码格式一样:将一个汉字编码为%uxxxx格式
不会被window.escape编码的字符有:@ _ - . * / + 
 
2.window.encodeURIComponent()与HttpUtility.UrlEncode()编码格式一样:将一个汉字编码为%xx%xx%xx的格式
不会被window.encodeURIComponent编码的字符有:‘  (  )  *  -  . _   ! ~   
不会被HttpUtility.UrlEncode编码的字符有:‘  (  )  *  -  .  _  ! 相比较而言,HttpUtility.UrlEncode比window.encodeURIComponent多一个 ~ 编码
 
3.不会被window.encodeURI编码的字符有: -  _  .  !  * (  )  ;  /  ?  :  @  &  =  $  ,  #,与encodeURIComponent对比,发现encodeURI不对:;/?:@&=+$,#这些用于分隔 URI 组件的标点符号进行编码
 
 
参考博文地址:

1.4 正则表达式工具

解析返回的请求,如果是html格式的,就需要解析一下返回的结果。简单的话可以直接用正则表达式解析。反正我就是这么干的。

2 常遇到的问题

2.1 编码问题

(1)返回的信息为空
最开始,用chrome找目标请求,按照Header上的信息构造请求。结果发现怎么都不行,返回都是空。后来发现是编码问题,从chrome上看到的是编码之前的信息,从fiddler上面才能看到原始的请求。
(2)请求之后,结果跟页面上操作的不一致
我创单的时候,明明是有儿童,而且有不同性别的人创单。结果创单之后全部变成女性,全部是成人。我找了好久这个问题,仍然从chrome上一一检查参数发现没有什么问题,直到我看raw请求的时候,我才发现一个是编了码的,一个是没有编码的。一般请求都会进行编码,只是数字和字母基本上编码之后都是一样的,所以没有进行编码就访问了。只要有中文和某些特殊字符就必须要编码,否则可能会引起错误。

2.2 cookie问题

(1)报500,内部服务器错误
自己测的时候没问题,一发布测试就出问题,报500,内部服务器错误。后来才发现是cookie问题,重新登录一下就可以了。原因推测是,因为每次登录成功之后都会存redis,下次再请求,从redis中获取cookie发送请求。因为存redis中的cookie的过期时间跟网站的不一致,也就是网站本身对这个cookie已经失效了,而redis中还存有这个cookie。后来的解决办法是,一遇到这种报500就重新再登录一次。
(2)远程服务器返回错误: (600)
没有登录起,Cookie不对。

2.3代理IP的问题

报字符串格式不正确,这些报错信息有时候并不能说明什么问题,只有解决了这个问题之后,才能发现确实是这个问题。我的意思是,不一定请求过去报输入字符串格式不正确就是代理IP的问题。但是如果我一解决了代理IP的问题,这个报错就解决了。那么我推测是这就是代理IP引起的。
技术分享
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Business
{
    /// <summary>
    /// HttpCallHelper
    /// </summary>
    public class HttpCallHelper
    {
        /// <summary>
        /// post
        /// </summary>
        /// <param name="param">param</param>
        /// <returns>HttpResultInfo</returns>
        public static HttpResultInfo Post(HttpRequestParams param)
        {
            HttpResultInfo res = null;
            try
            {
                param.RequestEncoding = Encoding.Default;
                byte[] bs = param.RequestEncoding.GetBytes(param.Data);
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(param.Url);
                req.Method = "POST";
                req.ContentType = "application/x-www-form-urlencoded";
                req.ContentLength = bs.Length;
                if (!string.IsNullOrEmpty(param.Cookie))
                {
                    req.Headers[HttpRequestHeader.Cookie] = param.Cookie;
                }
                req.Referer = param.Cookie;
                using (Stream reqStream = req.GetRequestStream())
                {
                    reqStream.Write(bs, 0, bs.Length);
                }
                string strResponse = string.Empty;
                HttpWebResponse httpResponse = (HttpWebResponse)req.GetResponse();
                using (Stream responseStream = httpResponse.GetResponseStream())
                {
                    Stream stream = responseStream;
                    StreamReader streamReader = new StreamReader(stream, param.ResponseEncoding);
                    strResponse = streamReader.ReadToEnd();
                    streamReader.Close();
                }
                string retcookie = req.GetResponse().Headers["Set-Cookie"];
                res = new HttpResultInfo()
                {
                    Cookie = retcookie,
                    StatusCode = httpResponse.StatusCode,
                    StatusDescription = httpResponse.StatusDescription,
                    Headers = httpResponse.Headers,
                    ErrorMsg = string.Empty,
                    Html = strResponse,
                    ResponseUrl = httpResponse.ResponseUri,
                };
                return res;
            }
            catch (Exception esx)
            {
                res = new HttpResultInfo()
                {
                    ErrorMsg = esx.Message.ToString(),
                };
                Console.WriteLine(esx.Message.ToString());
            }
            return res;
        }
        /// <summary>
        /// Get
        /// </summary>
        /// <param name="httpParam">httpParam</param>
        /// <param name="param">param</param>
        /// <returns>结果</returns>
        public static HttpResultInfo Get(HttpRequestParams httpParam, Dictionary<string, string> param)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in param)
            {
                sb.AppendFormat("{0}={1}&", item.Key, item.Value);
            }
            httpParam.Data = sb.ToString();
            return Get(httpParam);
        }
        /// <summary>
        /// Get
        /// </summary>
        /// <param name="param">param</param>
        /// <returns>结果</returns>
        public static HttpResultInfo Get(HttpRequestParams param)
        {
            HttpResultInfo ret = null;
            try
            {
                string strResult = string.Empty;
                HttpWebRequest httpRequest;
                HttpWebResponse httpResponse;
                string urlStr = param.Url;
                if (!string.IsNullOrEmpty(param.Data))
                {
                    urlStr = string.Format("{0}{1}", param.Url + "?", param.Data);
                }
                httpRequest = (HttpWebRequest)WebRequest.Create(new Uri(urlStr));
                httpRequest.Timeout = param.Timeout;
                httpRequest.Method = "Get";
                httpRequest.ContentType = param.ContentType;
                if (!string.IsNullOrEmpty(param.Cookie))
                {
                    httpRequest.Headers[HttpRequestHeader.Cookie] = param.Cookie;
                }
                //// 获取提交返回信息
                httpResponse = (HttpWebResponse)httpRequest.GetResponse();
                string returnStr = string.Empty;
                using (Stream st = httpResponse.GetResponseStream())
                {
                    returnStr = new StreamReader(st, param.ResponseEncoding).ReadToEnd();
                }
                string cookie1 = httpResponse.Headers["Set-Cookie"];
                ret = new HttpResultInfo()
                {
                    Cookie = cookie1,
                    StatusCode = httpResponse.StatusCode,
                    StatusDescription = httpResponse.StatusDescription,
                    Headers = httpResponse.Headers,
                    ErrorMsg = string.Empty,
                    Html = returnStr,
                    ResponseUrl = httpResponse.ResponseUri,
                };
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString().ToString());
                ret = new HttpResultInfo()
                {
                    Html = string.Empty,
                    ErrorMsg = ex.Message.ToString(),
                    Cookie = string.Empty,
                };
            }
            return ret;
        }
        /// <summary>
        /// GetQueryString
        /// </summary>
        /// <param name="param">param</param>
        /// <returns>结果</returns>
        public static string GetQueryString(Dictionary<string, string> param)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in param)
            {
                sb.AppendFormat("{0}={1}&", item.Key, item.Value);
            }
            if (sb.Length > 0)
            {
                sb = sb.Remove(sb.Length - 1, 1);
            }
            return sb.ToString();
        }
    }
    /// <summary>
    /// 请求消息
    /// </summary>
    public class HttpRequestParams
    {
        /// <summary>
        /// 请求编码
        /// </summary>
        private Encoding requestEncoding = Encoding.Default;
        /// <summary>
        /// 响应编码
        /// </summary>
        private Encoding responseEncoding = Encoding.Default;
        /// <summary>  
        /// 请求超时时间(以毫秒为单位,默认180秒)  
        /// </summary>  
        private int timeout = 180000;
        /// <summary>  
        /// 请求返回类型(默认text/html)
        /// </summary>  
        private string contentType = "text/html";
        /// <summary>
        /// HttpRequestParams
        /// </summary>
        public HttpRequestParams()
        {
        }
        /// <summary>
        /// 请求地址
        /// </summary>
        public string Url
        {
            get;
            set;
        }
        /// <summary>
        /// 数据
        /// </summary>
        public string Data
        {
            get;
            set;
        }
        /// <summary>
        /// Cookie
        /// </summary>
        public string Cookie
        {
            get;
            set;
        }
  
        /// <summary>
        /// ContentType
        /// </summary>
        public string ContentType
        {
            get { return this.contentType; }
            set { this.contentType = value; }
        }
        /// <summary>
        /// Referer
        /// </summary>
        public string Referer
        {
            get;
            set;
        }
        /// <summary>
        /// Timeout
        /// </summary>
        public int Timeout
        {
            get { return this.timeout; }
            set { this.timeout = value; }
        }
        /// <summary>
        /// RequestEncoding
        /// </summary>
        public Encoding RequestEncoding
        {
            get { return this.requestEncoding; }
            set
            {
                if (value == null)
                {
                    throw new Exception("请求编码格式不能设置为空!");
                }
                this.requestEncoding = value;
            }
        }
        /// <summary>
        /// 返回编码
        /// </summary>
        public Encoding ResponseEncoding
        {
            get { return this.responseEncoding; }
            set
            {
                if (value == null)
                {
                    throw new Exception("响应编码格式不能设置为空!");
                }
                this.responseEncoding = value;
            }
        }
    }
    /// <summary>
    /// 返回消息
    /// </summary>
    public class HttpResultInfo
    {
        /// <summary>
        /// Html
        /// </summary>
        public string Html
        {
            get;
            set;
        }
        /// <summary>
        /// Cookie
        /// </summary>
        public string Cookie
        {
            get;
            set;
        }
        /// <summary>
        /// IsSuccess
        /// </summary>
        public HttpStatusCode StatusCode
        {
            get;
            set;
        }
        /// <summary>
        /// ErrorMsg
        /// </summary>
        public string ErrorMsg
        {
            get;
            set;
        }
        /// <summary>
        /// 状态描述
        /// </summary>
        public string StatusDescription { get; set; }
        /// <summary>
        /// 响应头
        /// </summary>
        public WebHeaderCollection Headers { get; set; }
        /// <summary>
        /// 返回Uri
        /// </summary>
        public Uri ResponseUrl { get; set; }
    }
}
View Code

4 举个简单的例子

技术分享

 
 
 
 

C#爬页面总结

标签:

原文地址:http://www.cnblogs.com/tianxue/p/5462924.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!