苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 8623|回复: 3

[源码分享] C#使用Socket登陆WordPress源码

[复制链接]
发表于 2014-1-24 12:51:56 | 显示全部楼层 |阅读模式
就在昨晚,在本屌丝刚刚发布屌丝与女神的回忆史《C#外挂QQ找茬辅助源码,早期开发》后,在苏飞大哥的技术讨论群有个群友提出一个问题。使用http协议模拟工具可以登录成功Wordpress但是自己写代码死活登陆不上。本人玩Wordpress已经很多年了,在很多年前还没有女神的时候就开始有开发Wordpress客户端的冲动。最终都不了了之。今天群友提出的问题让我重拾以前的那份冲动….说多了,言归正传
本屌最开始也是使用苏飞大哥写的Httphelper类。也是死活登陆不上,取不到登陆之后的Cookie值。最后就在想,为什么Fiddler里面看到的报文跟我发过去的都差不多而不行呢。可能是在访问的时候某些参数不正确吧,那我把发送过去的报文做成一模一样的应该没有问题吧。所以下面用到了Socket访问80端口的形式发送报文..(下载地址在最后) C#使用Socket登陆Wordpress.png
使用Socket方式发送报文以及提取Cookie并访问网站的代码:
[C#] 纯文本查看 复制代码
class loginwp
{
    public string PostData(string postURL, string postString, string encoding)
    {
        string strHTML = "";//用来保存获得的HTML代码
        Uri URI = new Uri(postURL);
        string sendString;
        sendString = "POST {0} HTTP/1.1\r\n";
        sendString += "Host: {1}\r\n";
        sendString += "User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0\r\n";
        sendString += "Content-Type:application/x-www-form-urlencoded\r\n";
        sendString += "Content-Length:{2}\r\n";
        sendString += "Connection:close\r\n";
        sendString += "Cookie:wordpress_test_cookie=WP+Cookie+check\r\n\r\n";
        sendString += "{3}\r\n";
        sendString = string.Format(sendString, URI.PathAndQuery, URI.Host, postString.Length, postString);
        Byte[] ByteGet = Encoding.GetEncoding(encoding).GetBytes(sendString);
        IPAddress hostadd = Dns.GetHostEntry(URI.Host).AddressList[0];
        IPEndPoint EPhost = new IPEndPoint(hostadd, 80);
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        s.Connect(EPhost);
        if (!s.Connected)
        {
            strHTML = "链接主机失败";
        }
        s.Send(ByteGet, ByteGet.Length, SocketFlags.None);
        strHTML = Recv(s, Encoding.GetEncoding(encoding));
        return strHTML;
    }

    public static String Recv(Socket sock, Encoding encode)
    {
        Byte[] buffer = new Byte[1024];
        StringBuilder sb = new StringBuilder();

        Thread.Sleep(50);//根据页面响应时间进行微调        
        Int32 len = sock.Receive(buffer);
        sb.Append(encode.GetString(buffer, 0, len));

        while (sock.Available > 0)
        {
            Thread.Sleep(300);//也可以视情况微调           
            Array.Clear(buffer, 0, buffer.Length);
            len = sock.Receive(buffer);
            sb.Append(encode.GetString(buffer, 0, len));
            string ss = encode.GetString(buffer, 0, len);
        }
        sock.Close();
        return sb.ToString();
    }

    /// <summary>
    /// 从返回的源代码中提取cookies 以及301或302跳转
    /// </summary>
    /// <param name="s"></param>
    /// <param name="location"></param>
    /// <returns></returns>
    public string GetCookies(string html, out string location)
    {
        StringBuilder sbCookies = new StringBuilder();
        location = string.Empty;
        string[] arr = html.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string str in arr)
        {
            if (str.StartsWith("Set-Cookie: "))
            {
                int intStart = str.IndexOf(";");
                string strCookie = str.Substring(12, intStart - 11);
                sbCookies.Append(strCookie);
            }
            if (str.StartsWith("Location:"))
            {
                location = str.Substring(10);
            }
        }
        return sbCookies.ToString();
    }

    /// <summary>
    /// 带上cookies 获取需要登录验证的页面
    /// </summary>
    /// <param name="url">请求的URL</param>
    /// <param name="cookies">cookies字符串</param>
    /// <param name="encoding">页面编码</param>
    /// <returns></returns>
    public string GetPage(string url, string cookies, string encoding)
    {
        Uri URI = new Uri(url);
        string strHTML = string.Empty;//用来保存获得的HTML代码
        IPHostEntry gist = Dns.GetHostEntry(URI.Host);//获得当前url的ip地址
        IPAddress ip = gist.AddressList[0];//提取IP地址
        IPEndPoint ipEnd = new IPEndPoint(ip, 80);//封装IP地址和端口
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//实例化Stock
        try
        {
            socket.Connect(ipEnd);
        }//自动循环捕捉连接
        catch
        { }
        string sendString = "GET " + URI.PathAndQuery + " HTTP/1.1\r\n";
        sendString += "Connection:close\r\n";
        sendString += "Content-Type: application/x-www-form-urlencoded\r\n";
        sendString += "Host:" + URI.Host + "\r\n";
        if (!string.IsNullOrEmpty(cookies))
            sendString += "Cookie:" + cookies + "\r\n\r\n";
        byte[] ms = UTF8Encoding.GetEncoding(encoding).GetBytes(sendString);//将头部转换成byte形式
        socket.Send(ms);//发送
        int recv = -1;//定义接受数据长度
        byte[] data = new byte[1024];//用来保存接收数据
        do
        {
            recv = socket.Receive(data);
            strHTML += Encoding.GetEncoding(encoding).GetString(data, 0, recv);
        } while (recv != 0);
        return strHTML;
    }
}

最后放上Demo:C#使用Socket登陆Wordpress.zip


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2014-1-24 14:48:13 | 显示全部楼层
kovin 您好,
引用:“本屌最开始也是使用苏飞大哥写的Httphelper类。也是死活登陆不上,取不到登陆之后的Cookie值。最后就在想,为什么Fiddler里面看到的报文跟我发过去的都差不多而不行呢。”

我和你一样开始老用苏飞大哥的类死活登陆不上,后来看了您写的例子对比抓包发现httphelp类里面的cookie是包含 expired 域的字符串,问题出在这里(后面发现苏飞大哥在那群友问题解答的帖子里面说道新的httphelp类的cookie返回值需要配合HttpCookieHelper处理类使用)。
支持下您~{:soso_e179:},
文字表达能力不行~望谅解
 楼主| 发表于 2014-1-24 14:55:20 | 显示全部楼层
无法浏览网页 发表于 2014-1-24 14:48
kovin 您好,
引用:“本屌最开始也是使用苏飞大哥写的Httphelper类。也是死活登陆不上,取不到登陆之后的 ...

嗯。明白了。在httpclient处理cookie还真是不方便。下次再多学习一下苏飞大哥的httphelper.
发表于 2014-10-8 15:14:21 | 显示全部楼层
登陆成功,谢谢         飞哥的东西都说好,可就是用不来- -
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-12-27 12:02

© 2014-2021

快速回复 返回顶部 返回列表