CSDN结贴机--清洁工2008版

这个工具是方便版主结贴而设计,利用正则分析帖子的内容加上CSDN提供的API。
仅仅作为小技术分享帖。

将要处理的帖子链接放到“Topics.txt”文件中,如:
---Topics.txt---
http://topic.csdn.net/u/20080612/09/1a80296f-ac45-4efd-97ba-f9dd60a9a93f.html
http://topic.csdn.net/u/20080612/09/971b98b6-9ba6-4a0a-8ae8-c8baf3ccf064.html

将帖子里两部分合并保存为.hta文件,即可直接运行。

日志将放到log.txt文件中


<html>
<title>CSDN结贴机--清洁工2008版</title>
<head>
    <hta:application id="sofa" icon="sofa.ico" />
</head>
<body>
<div>
    用户名:<input type="text" id="TextUsername" />
    密码:<input type="password" id="TextPassword" />
    结贴方式:<select id="SelectCheckOutStyle"><option>按人平均</option><option>按楼平均</option><select/>
    <input type="button" value="开始结贴" onclick="ButtonStartClick();" id="ButtonStart" />
</div>
<div style="width:100%; height:80%">
    <textarea id="TextareaLog" style="width:100%; height:100%"></textarea>
</div>
<script language="javascript" type="text/javascript">
var ForAppending = 8; // 追加模式
var ForReading = 1; // 读取模式
var ForWriting = 2; // 写入模式

var fso = new ActiveXObject("Scripting.FileSystemObject"); // 文件系统
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); // http访问
var textareaLog = document.getElementById("TextareaLog"); // 日志文本框
var textUsername = document.getElementById("TextUsername"); // 用户名
var textPassword = document.getElementById("TextPassword"); // 密码
var selectCheckOutStyle = document.getElementById("SelectCheckOutStyle"); // 结贴方式

/// <summary>
/// 获得值在列表中的位置
/// </summary>
/// <param name="array">列表</param>
/// <param name="value">值</param>
/// <returns>返回值在列表中的位置</returns>
function IndexOf(array, value)
{
    for (var i = 0; i < array.length; i++)
        if (array[i] == value) return i;
    return -1;
}

/// <summary>
/// 读取文本文件中的字符串
/// </summary>
/// <param name="filename">文件名</param>
/// <returns>返回文本文件中的字符串</returns>
function GetFileText(filename)
{
    if (!fso.FileExists(filename)) return "";
    var istream = fso.OpenTextFile(filename, ForReading);
    if (!istream) return "";
    try
    {
        var contents = istream.ReadAll();
        istream.Close();
    }
    catch (e)
    {
        return "";
    }
    return contents;
}

/// <summary>
/// 将字符串追加到文本文件最后
/// </summary>
/// <param name="filename">文件名</param>
/// <param name="text">所要追加的字符串</param>
/// <returns>返回文本文件中的字符串</returns>
function AppendFileText(filename, text)
{
    var istream = fso.OpenTextFile(filename, ForAppending, true);
    if (!istream) return;
    try
    {
        istream.write(text);
        istream.Close();
    }
    catch (e)
    {
    }
}

/// <summary>
/// 将字符串写到文本文件最后
/// </summary>
/// <param name="filename">文件名</param>
/// <param name="text">所要追加的字符串</param>
/// <returns>返回文本文件中的字符串</returns>
function WriteFileText(filename, text)
{
    var istream = fso.OpenTextFile(filename, ForWriting, true);
    if (!istream) return;
    try
    {
        istream.write(text);
        istream.Close();
    }
    catch (e)
    {
    }
}

/// <summary>
/// 结贴
/// </summary>
/// <param name="username">用户名</param>
/// <param name="password">用户口令</param>
/// <param name="topicUrl">帖子链接</param>
/// <param name="forumId">版块ID</param>
/// <param name="points">给分列表</param>
/// <returns>返回反馈信息</returns>
function CheckOut(username, password, topicUrl, forumId, points)
{
    var contentText =
'<?xml version="1.0" encoding="utf-8"?>/n' +
'<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">/n' +
'    <soap12:Body>/n' +
'        <CheckOutTopic xmlns="http://www.csdn.net/">/n' +
'            <identity>/n' +
'                <username>' + username + '</username>/n' +
'                <password>' + password + '</password>/n' +
'            </identity>/n' +
'            <topicUrl>' + topicUrl + '</topicUrl>/n' +
'            <forumId>' + forumId + '</forumId>/n' +
'            <replyPoints>/n';
    for (var i = 0; i < points.length; i++)
    {
        if (parseInt(points[i].point) <= 0) continue; // 没有得分则不用提交
        contentText +=
'                <ReplyPoint>/n' +
'                    <replyId>' + points[i].replyId + '</replyId>/n' +
'                    <point>' + points[i].point + '</point>/n' +
'                </ReplyPoint>/n';
    }
    contentText +=
'            </replyPoints>/n' +
'        </CheckOutTopic>/n' +
'    </soap12:Body>/n' +
'</soap12:Envelope>/n';
    try
    {
        xmlhttp.open("post", "http://forum.csdn.net/OpenApi/forumapi.asmx", false);
        xmlhttp.setRequestHeader("CONTENT-LENGTH", contentText.length);
        xmlhttp.setRequestHeader("CONTENT-TYPE", "text/xml; charset=utf-8");
        xmlhttp.send(contentText);
        return xmlhttp.responseText;
    }
    catch (e)
    {
        return "";
    }
}

/// <summary>
/// 构造结贴给分信息
/// </summary>
/// <param name="replyId">回复Id</param>
/// <param name="point">给分点数</param>
/// <returns>返回给分信息</returns>
function PointInfo(replyId, point)
{
    this.replyId = replyId;
    this.point = point;
}
</script>

<script language="javascript" type="text/javascript">
/// <summary>
/// 读取页面文本
/// </summary>
/// <param name="url">页面所在链接</param>
/// <returns>返回页面文本</returns>
function GetUrlText(url)
{
    try
    {
        xmlhttp.open("get", url, false);
        xmlhttp.send();
        return xmlhttp.responseText;
    }
    catch (e)
    {
        return "";
    }
}

/// <summary>
/// 分析回复内容
/// </summary>
/// <param name="replyText">回复区域HTML文本</param>
/// <returns>返回回复信息</returns>
function ReplyInfo(replyText)
{
    var re = //<a/s*csdnid=/"replyId/"/s*name="(.*?)"/s*/>/<//a/>/s*<table/s*class=/"item reply/"/s*csdnid="(.*?)".*?>.*?/<//table/>/g;
    if (re.exec(replyText))    this.replyId = RegExp.$1; // 回复ID

    var re = //<a/s*href=/"http/:////hi.csdn.net//(.*?)/"/s*.*?/>/g;
    if (re.exec(replyText))    this.replyUser = RegExp.$1; // 回复用户名
    
    var re = //<var/s*csdnid=/'replyDate/'/>(.*?)/<//var/>/g;
    if (re.exec(replyText))    this.replyDate = RegExp.$1; // 回复时间
    
    var re = //<span/s*class=(/"|/')adminOpera(/"|/')/>/s*该回复于(.*?)被版主删除/s*/<//span/>/g;
    if (re.exec(replyText))    this.deleteDate = RegExp.$3; // 删除时间

    var re = //<span/s*class=(/"|/')adminOpera(/"|/')/>/s*该回复于(.*?)被版主修改/s*/<//span/>/g;
    if (re.exec(replyText))    this.modifyDate = RegExp.$3; // 修改时间
}

/// <summary>
/// 分析帖子内容
/// </summary>
/// <param name="topicText">帖子HTML文本</param>
/// <returns>返回帖子信息</returns>
function TopicInfo(topicText)
{
    topicText = topicText.replace(//r/n/g, " ");
    var re = //<span/s*csdnid=/"isCheckOut/"/s*class=/"color_red/"/>(.*?)/<//span/>/g;
    if (re.exec(topicText))    this.isCheckOut = RegExp.$1; // 是否已经结贴
    
    var re = //<meta/s*csdnid=/"sectionId/"/s*content=/"(.*?)/"(/s*//)*/>/g;
    if (re.exec(topicText))    this.forumId = RegExp.$1; // 版块ID
    
    var re = //<meta/s*id=/"topicViewUrl/"/s*csdnid=/"topicViewUrl/"/s*content=/"(.*?)/"(/s*//)*/>/g;
    if (re.exec(topicText))    this.topicUrl = RegExp.$1; // 帖子链接
    
    var re = //<meta/s*csdnid=/"description/"/s*content=/"(.*?)/"/s*name=/"description/"(/s*//)*/>/g;
    if (re.exec(topicText))    this.description = RegExp.$1; // 帖子主题
    
    var re = //<var/s*id=/"point/"/s*csdnid=/"topicPoint/"/>(.*?)/<//var/>/g;
    if (re.exec(topicText))    this.point = RegExp.$1; // 帖子点数

    var re = //<var/s*csdnid=/"replyCount/">(.*?)/<//var/>/g;
    if (re.exec(topicText))    this.replyCount = RegExp.$1; // 回复次数
    
    var re = //<a/s*href=/"http/:////hi.csdn.net//(.*?)/"/s*.*?/>/g;
    if (re.exec(topicText))    this.username = RegExp.$1; // 楼主
    
    var re = //<var/s*csdnid=/"topicPostDate/">(.*?)/<//var/>/g;
    if (re.exec(topicText))    this.topicPostDate = RegExp.$1; // 发帖时间
    
    var matchs = topicText.match(//<a/s*csdnid=/"replyId/"/s*name="(.*?)"/s*/>/<//a/>/s*<table/s*class=/"item reply/"/s*csdnid="(.*?)".*?>.*?/<//table/>/g);
    this.replys = new Array();
    for (var i = 0; matchs && i < matchs.length; i++)
    {
        var replyInfo = new ReplyInfo(matchs[i]);
        this.replys.push(replyInfo);
    }
}

/// <summary>
/// 分析错误信息
/// </summary>
/// <param name="errorText">服务器返回的XML文本</param>
/// <returns>返回错误信息</returns>
function ErrorInfo(errorText)
{
    errorText = errorText.replace(//r/n/g, " ");
    var re = //<errId/>(.*?)/<//errId/>/g;
    if (re.exec(errorText))    this.errId = RegExp.$1; // 错误号

    var re = //<errInfo/>(.*?)/<//errInfo/>/g;
    if (re.exec(errorText))    this.errInfo = RegExp.$1; // 错误信息
}

/// <summary>
/// 添加日志
/// </summary>
/// <param name="text">日志文本</param>
function AppendLog(text)
{
    if (textareaLog) textareaLog.value += text;
    AppendFileText("log.txt", text);
}

var topics = GetFileText("Topics.txt").split(//r/n/); // 帖子列表

/// <summary>
/// 开始按钮点击事件
/// </summary>
function ButtonStartClick()
{
    for (var j = 0; j < topics.length; j++)
    {
        var text = GetUrlText(topics[j]); // 获得帖子的网页文本
        var topicInfo = new TopicInfo(text); // 分析网页文本中的帖子信息
        if (topicInfo.isCheckOut)
        {
            AppendLog("错误:" + topicInfo.topicUrl + "已经结过。/r/n");
            continue;
        }
        
        var points = new Array();
        var names = new Array();
        for (var i = 0; parseInt(topicInfo.point) > 0 && i < topicInfo.replys.length; i++) // 帖子分数需要大于0
        {
            // TODO : 判断回复的日期可以用topicInfo.replys[i].replyDate
            if (topicInfo.replys[i].deleteDate)    continue; // 已被删除的回复
            if (topicInfo.replys[i].replyUser.toLowerCase() == textUsername.value.toLowerCase()) continue; // 回复用户等于结贴用户
            if (topicInfo.replys[i].replyUser.toLowerCase() == topicInfo.username.toLowerCase()) continue; // 回复用户等于楼主
            switch (selectCheckOutStyle.selectedIndex) // 结贴的方式
            {
                case 0: // 按人平均
                    if (IndexOf(names, topicInfo.replys[i].replyUser.toLowerCase()) < 0) // 判断已经给过分了
                    {
                        points.push(new PointInfo(topicInfo.replys[i].replyId, 0));
                        names.push(topicInfo.replys[i].replyUser.toLowerCase());
                    }
                    break;
                case 1: // 按楼平均
                    points.push(new PointInfo(topicInfo.replys[i].replyId, 0));
                    break;
            }
        }
        
        if (parseInt(topicInfo.point) > 0 && points.length <= 0) // 有分,但没有符合得分条件的回复
        {
            AppendLog("错误:" + topicInfo.topicUrl + "没有符合得分条件的回复。/r/n");
            continue;
        }
        
        if (points.length > 0)
        {
            var average = Math.floor(parseInt(topicInfo.point) / points.length); // 获得平均分
            var spare = parseInt(topicInfo.point) % points.length; // 获得余数
            for (var i = 0; i < points.length; i++)
            {
                if (spare > 0)
                {
                    points[i].point = average + 1;
                    spare--;
                } else points[i].point = average;
            }
        }
        
        var errorText = CheckOut(textUsername.value, textPassword.value, topicInfo.topicUrl, topicInfo.forumId, points);
        var errorInfo = new ErrorInfo(errorText);
        if (parseInt(errorInfo.errId) == 0) // 没有错误
            AppendLog("成功:" + topicInfo.topicUrl + "已经结贴。/r/n");
        else AppendLog("错误:" + topicInfo.topicUrl + "#" + errorInfo.errId + " 原因:" + errorInfo.errInfo + "/r/n");
    }
}
</script>
</body>
</html>
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页