这个工具是方便版主结贴而设计,利用正则分析帖子的内容加上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>
分享到:
相关推荐
Csdn收音机 - 我们的IT学习机 - 元旦特别版 - (Csdn论坛助手源代码) 了解更多: http://blog.csdn.net/boringame/archive/2011/01/02/6111984.aspx
CSDN阅读器最新版--附源代码 CSDN阅读器最新版--附源代码 CSDN阅读器最新版--附源代码
Csdn收音机-我们的IT学习机-元旦特别版发布(Csdn论坛助手,含源码) 了解更多: http://blog.csdn.net/boringame/archive/2011/01/02/6111984.aspx
基本环境试验规程.第2-64部分试验.试验Fh振动、宽带随机抽样
CSDN新版论坛自动给分的Maxthon插件,可以大大减轻结贴,特别是有N多回复帖的痛苦. <br>本来想试着做个FireFox的插件的. 照着例子做了半天发现不知道怎么在页面执行脚本. 所以只做了Maxthon的. <br>具体...
如果你关注某个技术而不限制语言,你可以用这个工具,设置关键字,在csdn未结贴的帖子列表中查询自己感兴趣的主题。相当于根据你的兴趣爱好定制自己的板块,所有你需要关注的未解决的问题,立刻呈现。
宋宝华 - 深入探究Linux设备树CSDN讲座ppt。详细的论述的device tree的方方面面。
CSDN技术公开课《Android自动化测试之UIAutomator》PPT
CSDN技术主题月第一期-《直播技术架构新解读》嘉宾PPT
CSDN博客备份工具blogspider,可以备份自己所有的CSDN博客到本地,也可以备份别人的博客。若需要保存别人的技术博客或自己的问题,blogspider可以帮你达到目的。若blogspider程序出现问题,可以关注我的CSDN博客,...
CSDN Share 是一款出色的Android阅读工具,阅读由 CSDN社区用户分享的技术文档。 通过CSDN Share可以在线阅读或离线下载CSDN 举办的各类技术活动的精彩讲义,以及来自CSDN下载社区由用户分享的技术文档。 马上下载...
adt-bundle-windows-x86-20140624
非常好用的爬虫工具,如果你关注某个技术而不限制语言,你可以用这个工具,设置关键字,在csdn未结贴的帖子列表中查询自己感兴趣的主题。相当于根据你的兴趣爱好定制自己的板块,所有你需要关注的未解决的问题,立刻...
csdn自带的介绍范文模板 如果写过一次博客,这个文档就找不到了(没有恢复到本模板的url) 就在这里备份一下 方便查阅
ARM Cortex-M0权威指南-中文带目录,ARM公司的Cortex-M0应用于各种微控制器(MCU)中,并可让研发工程师以8位的价位创造32位的的效能,并将传统的8位和16位的处理器升级到更高效、更低功耗的32位处理器。
福昕Foxit PDF编辑器破解版福昕Foxit PDF编辑器破解版
计算机网络期末试卷csdn整合版计算机网络期末试卷csdn整合版计算机网络期末试卷csdn整合版计算机网络期末试卷csdn整合版计算机网络期末试卷csdn整合版计算机网络期末试卷csdn整合版计算机网络期末试卷csdn整合版...
开发环境 eclipse for jee+jdk7+tomcat7 lucene4.4+crawler4j3.5 索引文件位置:/csdn-blog-crawler/data 记得把生成的索引放入:/csdn-blog-crawler/WebContent
中文版最新版jquery-1.6.2-vsdoc.js jQuery的VS智能提示插件 建议下载该资源的朋友收藏我的csdn下载地址http://jehnjehn.download.csdn.net/,我以后会一直跟进更新vsdoc文档的下载,只要官方更新,我会在最短时间...
程序通过分析CSDN博客源码来生成一些必要的数据,可能在以后使用当中出现爬取不了的情况,可能是CSDN的源码结构修改了。程序只是用于学习之用,严禁用于非法目的而照成CSDN服务器过载。 由于生成PDF的时候需要依赖...