首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Socket 模擬 HTTP 實現 WordPress 自動發文:登錄篇

     編輯:關於C語言

背景與動機

公司需從自有文章平台一鍵發布到 WordPress 站群。初嘗 HttpWebRequest 發現 Cookie 接收不全,導致登錄失敗。改用 Socket 手工構造 HTTP 報文,完全掌控 Cookie 與重定向,並可延伸至秒殺器等場景。

核心類結構

public class HttpSocketClient {
    // 1. GET 請求(攜帶 Cookie)
    public string GetPage(string url, string cookies, string encoding);

    // 2. POST 登錄(自行處理 Cookie)
    public string PostData(string postUrl, string postString, string encoding);

    // 3. 從回應解析 Cookie 與 Location(301/302)
    public string GetCookies(string html, out string location);
}

關鍵方法實現詳解

1. GetPage — 發送 GET 請求

public string GetPage(string url, string cookies, string encoding) {
    Uri uri = new Uri(url);
    string html = "";
    IPAddress ip = Dns.GetHostEntry(uri.Host).AddressList[0];
    IPEndPoint ep = new IPEndPoint(ip, 80);
    Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    try { sock.Connect(ep); } catch { /* 簡易重試邏輯省略 */ }

    // 構造 HTTP 頭
    string req = "GET " + uri.PathAndQuery + " HTTP/1.1\r\n";
    req += "Connection: close\r\n";
    req += "Content-Type: application/x-www-form-urlencoded\r\n";
    req += "Host: " + uri.Host + "\r\n";
    if (!string.IsNullOrEmpty(cookies))
        req += "Cookie: " + cookies + "\r\n\r\n";

    byte[] data = Encoding.GetEncoding(encoding).GetBytes(req);
    sock.Send(data);

    // 接收回應
    byte[] buf = new byte[1024];
    int recv;
    do {
        recv = sock.Receive(buf);
        html += Encoding.GetEncoding(encoding).GetString(buf, 0, recv);
    } while (recv != 0);

    return html;
}

注意: 真實專案需處理 Chunked 編碼、Content-Length、HTTPS (SSL/TLS)、超時重試等,此處為教學簡化版。

2. PostData — 發送 POST 登錄

public string PostData(string postUrl, string postString, string encoding) {
    Uri uri = new Uri(postUrl);
    string req = string.Format(
        "POST {0} HTTP/1.1\r\n" +
        "Host: {1}\r\n" +
        "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0\r\n" +
        "Content-Type: application/x-www-form-urlencoded\r\n" +
        "Content-Length: {2}\r\n" +
        "Connection: close\r\n\r\n" +
        "{3}\r\n",
        uri.PathAndQuery, uri.Host, postString.Length, postString);

    byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(req);
    IPAddress ip = Dns.GetHostEntry(uri.Host).AddressList[0];
    IPEndPoint ep = new IPEndPoint(ip, 80);
    Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    s.Connect(ep);
    if (!s.Connected) return "連接失敗";

    s.Send(bytes, bytes.Length, SocketFlags.None);
    return Recv(s, Encoding.GetEncoding(encoding)); // Recv 同 GetPage 接收邏輯
}

3. GetCookies — 解析 Set-Cookie 與 Location

public string GetCookies(string html, out string location) {
    StringBuilder sb = new StringBuilder();
    location = "";
    string[] lines = html.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string line in lines) {
        if (line.StartsWith("Set-Cookie: ")) {
            int semi = line.IndexOf(';');
            string cookie = line.Substring(12, semi - 11); // 取 name=value
            sb.Append(cookie).Append("; ");
        }
        else if (line.StartsWith("Location:")) {
            location = line.Substring(10).Trim();
        }
    }
    return sb.ToString().TrimEnd(';', ' ');
}

登錄流程:POST /wp-login.php → 解析 Set-Cookie → 若有 Location 則 GET 重定向 → 後續請求攜帶 Cookie。

實戰截圖

登錄成功截圖

避坑指南

  • Cookie 容器: 生產環境建議封裝 CookieContainer 自動管理。
  • HTTPS: 需用 SslStream 包裝 Socket,或直接改用 HttpClient (現代 .NET 首選)。
  • 編碼: 嚴格對應伺服器 charset,否則中文亂碼。
  • WordPress Nonce: 發文需解析頁面中的 _wpnonce 隱藏欄位,攜帶在 POST 中。

擴展:秒殺器雛形

同樣原理,只需:

  1. 分析目標站點請求參數、加密簽名算法。
  2. 高併發 Socket 池 + 精準定時觸發。
  3. 應對反爬蟲:IP 代理池、指紋偽裝、驗證碼識別。

提醒: 任何自動化腳本請遵守目標站點 robots.txt 及法律法規,切勿濫用。

交流群

  • .NET 技術研究 QQ 群:41050480
  • 合肥軟件開發技術聯盟:31065717

歡迎大俠們拋磚引玉,共同精進!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved