作者:Monyer
来源:梦之光芒

Monyer自己也知道,现在的软件成天的Alpha1、Alpha2...Beta1、Beta2...Preview1、Preview2...Sp1、Sp2很讨厌,成天没事总升级玩了。但是Monyer似乎没有突破这个传统——百度空间文章提取工具Alpha2。

原因很简单——在我认为基本上完成它需要几个月的时间(我需要学习等等),所以必然不喜欢期间老版本的一些蹩脚的功能使大家反感,另外也希望每次更新大家的评论能给我一些建议,不至于画蛇添足。

简单介绍一下对这个东西的开发版本控制(在功能开发阶段会延续Alpha版本,在测试完善阶段会发布Beta版,直到相当完善了再发布正式版给大家,望理解)

所以熟话说“先明后不争”:如果只是为了尝鲜的好友,那么可以使用Alpha的版本,虽然有可能不稳定,但是毕竟有新的东西;希望舒舒服服使用好功能的好友,可以使用Beta中的版本,基本上稳定,只是有可能会有些Bug;而那些只想使用稳定的版本并且不着急新功能的好友,就等待正式版的发布吧!

这里说明一下,就是怕大家误会我“没事闲的,弄出这么多版本来”,每个人的时间精力是不同的,我不可能在很短时间内就开发出完整的版本来。

从这次开始,这个工具的名字从“百度空间文章列表提取工具”更改成了“百度空间文章提取工具”,这意味着可以备份自己的文章了。而文件格式也从原来的html改成了hta,也就说具有了彻底的本地执行的权限。

由于代码仍旧是javascript和vbscript纯脚本代码编写,所以有可能被某些杀毒软件误认为是vba病毒(目前仅AntiVir会认为是HTML/ADODB.Exploit.Gen),因为事实上这个脚本已经可以对数据库和文件进行操作了,所以你可以把它当成exe来对待——甚至比exe级别还高,因为大多数防火墙不会拦截它的数据包。虽然Monyer本人可以完全保证不在程序中放一条有损用户的代码,但不能保证在网络传播途中是否有变,因为毕竟是开源的东西,所以还请大家务必到Monyer.cn主站点进行下载!

程序由原来的单一的javascript变成了javascript和vbscript的混合应用,其中javascript主要用于处理数据,而 vbscript用于处理数据库,都是各自的强项嘛。同时这样做的原因也是为了大家学习代码方便,因为很少有人用jscript链接数据库或者用 vbscript做ajax或数据验证、dom操作。但整体性能没有太大影响,因为毕竟处理的数据量有限嘛。

在这个版本里正式加入了数据库功能,自动获取,自动验证,自动录入,以后还会加一些其他的功能,暂时不便详述。但对数据库操作用到了许多的系统控件,譬如ADOX.Catalog等,我用我的英文XP试过了,一切正常,不知道到了大家的电脑里反映会怎么样,还望大家把错误能及时反馈上来,我好做进一步的改正。

更多功能的加入意味着要编写更多的代码,目前代码已经从最初的300行狂涨到600行,估计我的第一个beta版本时能达到2000行。不过辛苦的是我,大家倒不用担心,2000行的代码的体积也未必会超过50k,这比相同功能编译后的软件体积要小。为了工具的完整性和易用性,我也会尽量把代码在一个页面来写。

目前这个工具的功能很简单——获取文章列表、获取文章、查看列表,而且容错和功能也不全面,实在不能说是什么什么1.0,2.0的,叫Alpha我还能心安些。

运行时会生成一个为monyer.mdb的数据库文件,算作本程序的唯一版权了,希望大家理解。这个东西最好不要随便改名字,里面也不要改表名列名什么的,因为升级的版本会兼容上一个版本的设置。

好了,大概就这样!大家可以到 http://monyer.cn/down 中下载,一共只有几个文件,所以不信大家找不到,嘿嘿。当然为了另一部分人学习,代码依然要公布一下,大家也可以把工具下载下来自己来看,里面虽然有基本的版权声明,但只要大家不要硬说这个东西是自己做的并在其他网站上发表。只是copy运用其中某些代码,我是不会介意的,互相学习交流嘛。

代码如下:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
    百度空间文章提取工具0.2
 
    Author:梦之光芒(Monyer)
    Email:monyer@126.com
    Blog:http://hi.baidu.com/monyer
    OICQ:2598841
    WEB:http://monyer.cn
 
正如你所见,这是一个针对百度空间的文章提取工具,拥有自己
的数据库和浏览功能。所有代码均为Javascript和Vbscript编写
因此所有代码均公开,可以互相传播或者进行个性化修改,方便
大家学习!但需要声明的是,Monyer本人保留该工具的版权和所
有权,所以一切侵犯作者权利的行为,Monyer有权利追究其责任
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>百度空间文章列表提取工具</title>
<style>
*{
font-size:12px
}
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
}
#menu{
background:buttonface;
padding:3px 10px;
}
#head{
text-align:center;
}
#choose{
display: none;
}
#error{
display:none;
}
.count{
width:8%;display: block;float: left; +overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.tit{
width:50%;display: block;float: left; +overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.date{
width:20%;display: block;float: left; +overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.clg{
width:20%;display: block;float: left; +overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.clear{
clear:both;
}
</style>
</head>
<script language="javascript" type="text/javascript">
var version = "0.2"
var XmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
var getlist_html = "";
var count;
var timer = 1000;
var i;
var start;
var mid;
var end;
var isArtclg;
var text = "";
var text2 = "";
var texts;
var user = "";
var BlogUrl = "";
var BlogListUrl = "";
var ArticleUrl = "";
var page = 0;
var page_end;
var page_min;
var page_max;
var page_min_value;
var page_max_value;
var artclg;
var artclg_a = "<div id=\"m_artclg\" class=\"modbox\">";//文章类别
var artclg_b = "<div id=\"mod_filed\" class=\"mod\">";
var artclg_i = "<div class=\"line\">";
var artclg_c = "title=\"查看该分类中所有文章\">";
var artclg_d = "</a>";
var page_a = "[下一页]";//获取页数
var page_b = "[尾页]";
var page_c = "/blog/index/";
var page_d = "\">";
var bloglist_a = "<div id=\"m_blog\" class=\"modbox\">";//获取文章列表
var bloglist_b = "function setpv(allnum)";
var bloglist_i = "<div class=\"line\">";
var bloglist_mid = "innerHTML = tps;";
var tit;
var tit_a = "target=\"_blank\">";
var tit_b = "</a></div>";
var url;
var url_a = "/blog/item/";
var url_b = ".html";
var date ;
var date_a = "<div class=\"date\">";
var date_b = "</div>";
var clg;
var clg_a = ">类别:";
var clg_b = "</a>";
var art;
var art_a = "<div class=\"cnt\">";
var art_b = "<div class=\"opt\">";

//****************************功能函数区****************************

function $(id){
   return document.getElementById(id);
}

function Listening(){                    //按钮事件监听
   $("initialize").onclick = function(){
    getInitialize();
   };
 
   $("getList").onclick = function(){
    page_min_value = $("page_min").value;
    page_max_value = $("page_max").value;
    page = page_min_value;
    isArtclg = $("isArtclg").checked;
    artclg = $("artclg").value;
    count = 1;
    getList();
   };
 
   $("b_getlist").onclick = function(){
    $("allbody").innerHTML = getlist_html;
    Listening();
   };
 
   $("b_getart").onclick = function(){
    $("allbody").innerHTML = "";
    count = 1;
    getArt();
   };
 
   $("b_viewlist").onclick = function(){
    $("allbody").innerHTML = "";
    count = 1;
    viewList();
   };
 
   $("b_search").onclick = function(){
    $("allbody").innerHTML = "";
    alert("b_search");
   }
}

function getHtml(url,fun){               //XmlHttpRequest调用
   XmlHttp.Open("get",url,true);
   XmlHttp.Send(null);
   XmlHttp.onReadyStateChange = function(){
    if(XmlHttp.readyState==4){
     if(XmlHttp.status==200){
      text = XmlHttp.responsetext;
      setTimeout(fun,timer);
     }else{
      $("error").style.cssText = "display:block;text-align:center;";
      $("error").insertAdjacentHTML("beforeEnd",url+"<br />");
     }
    }
   };
}

function UrlEncode(str){                //Url编码
   var ret="",tt="";
   var strSpecial="!\"#$%&'()*+,/:;<=>?[]^`{|}~%";
   for(var i=0;i<str.length;i++){
    var chr = str.charAt(i);
    var c=str2asc(chr);
    tt+= chr+":"+c+"n";
    if(parseInt("0x"+c) > 0x7f){
     ret+="%"+c.slice(0,2)+"%"+c.slice(-2);
    }else{
     if(chr==" ")
      ret+="+";
     else if(strSpecial.indexOf(chr)!=-1)
      ret+="%"+c.toString(16);
     else
      ret+=chr;
    }
   }
   return ret;
}

function getUpdate(){
   getHtml("http://monyer.cn/Down/update/dohi.update.js","DoUpdate()");
   //getHtml("http://127.0.0.1/Down/update/dohi.update.js","DoUpdate()");
}
function DoUpdate(){
   eval(text);
   if(LatestVersion!=OldVersion){
    var isDown = window.confirm("发现新版本"+LatestVersion+",您目前的版本为"+OldVersion+",是否进行升级?");
    if(isDown){
     //getHtml(UpdateUrl,"DownUpdate()");
     DownUpdate(UpdateUrl);
    }else{
 
    }
   }
}

//**********************页面获取处理区******************************

function getInitialize(){
   if(user != $("blogurl").value) user = $("blogurl").value;
   else user += "/";
   BlogUrl = "http://hi.baidu.com/" + user + "/blog";
   getHtml(BlogUrl,"doInitialize()");
}

function doInitialize(){
   artclg_list = $("artclg");
   page_min = $("page_min");
   page_max = $("page_max");
   start = text.indexOf(artclg_a);
   end = text.indexOf(artclg_b);
   text2 = text.substring(start,end);
   texts = text2.split(artclg_i);
 
   for(i=0;i<texts.length-1;i++){
    start = texts[i].indexOf(artclg_c) + artclg_c.length;
    end = texts[i].indexOf(artclg_d);
    text2 = texts[i].substring(start,end);
    artclg_list.options[i] = new Option(text2, text2);
   }
 
   start = text.indexOf(page_a);
   end = text.indexOf(page_b);
   text2 = text.substring(start,end);
 
   start = text2.indexOf(page_c) + page_c.length;
   end = text2.indexOf(page_d);
   page_end = text2.substring(start,end);
 
   for(i=0;i<=page_end;i++){
    page_min.options[i] = new Option("第"+(i+1)+"页",i);
    page_max.options[i] = new Option("第"+(i+1)+"页",i);
   }
 
   $("choose").style.cssText = "display:block;text-align:center;";
}

function getList(){
   BlogList = "http://hi.baidu.com/" + user + "/blog/index/" + page;
   if(isArtclg) BlogList = "http://hi.baidu.com/" + user + "/blog/category/" + UrlEncode(artclg) + "/index/"+ page;
   if(page<=page_max_value){
     getHtml(BlogList,"doList();getList();");
   }else{
    alert("获取完成");
   }
   page++;
}

function doList(){
   start = text.indexOf(bloglist_a);
   end = text.indexOf(bloglist_b);
   text2 = text.substring(start,end);
   texts = text2.split(bloglist_i);
 
   for(i=0;i<texts.length-1;i++){
    start = texts[i].indexOf(url_a) + url_a.length;
    end = texts[i].indexOf(url_b);
    url = texts[i].substring(start,end);
 
    start = texts[i].indexOf(tit_a) + tit_a.length;
    end = texts[i].indexOf(tit_b);
    tit = texts[i].substring(start,end);
 
    start = texts[i].indexOf(date_a);
    mid = texts[i].indexOf(bloglist_mid) + bloglist_mid.length;
    texts[i] = texts[i].substring(start,mid);
 
    start = texts[i].indexOf(date_a) + date_a.length;
    end = texts[i].indexOf(date_b);
    date = texts[i].substring(start,end);
 
    start = texts[i].indexOf(clg_a);
    mid = texts[i].indexOf(bloglist_mid);
    texts[i] = texts[i].substring(start,mid);
 
    start = texts[i].indexOf(clg_a) + clg_a.length;
    end = texts[i].indexOf(clg_b);
    clg = texts[i].substring(start,end);
 
    text2 = "<div>";
    text2 += "<span class='count'> " + count + "</span>";
    text2 += "<span class='tit'><a href='http://hi.baidu.com/"+user+"/blog/item/"+url+".html' target='blank'>" + tit + "</a></span>";
    text2 += "<span class='date'>" + date + "</span>";
    text2 += "<span class='clg'>" + clg + "</span>";
    text2 += "<span class='clear'></span>";
    text2 += "</div>";
 
    $("list").insertAdjacentHTML("afterBegin",text2);
    //保存到数据库
    add(tit,url,clg,date,user);
 
    count++;
   }
}

function getArticle(Name,Url,UserName){
   if(Name!=0||Url!=0||UserName!=0){
    ArticleUrl = "http://hi.baidu.com/"+UserName+"/blog/item/"+Url+".html";
    Tit = Name;
    getHtml(ArticleUrl,"doArticle('"+Name+"');");
   }else{
    alert("获取完成!");
   }
}

function doArticle(Name){
   start = text.indexOf(art_a) + art_a.length;
   end = text.indexOf(art_b) - 32;
   art = text.substring(start,end);
 
   text2 = "<div>";
   text2 += "<span class='count'> " + count + "</span>";
   text2 += "<span class='tit'>" + Name + "</span>";
   text2 += "<span class='date'>OK!</span>";
   text2 += "<span class='clear'></span>";
   text2 += "</div>";
 
   saveArt(art);
   $("allbody").insertAdjacentHTML("afterBegin",text2);
   getEveryArt();
   count++;
}

//**********************数据库响应区********************************

function showList(Name,Url,Content,Category,pDate,UserName){
   text2 = "<div>";
   text2 += "<span class='count'> " + count + "</span>";
   text2 += "<span class='tit'><a title='"+UserName+"' href='http://hi.baidu.com/"+UserName+"/blog/item/"+Url+".html' target='blank'>" + Name + "</a></span>";
   text2 += "<span class='date'>" + new Date(Date.parse(pDate)).toLocaleString() + "</span>";
   text2 += "<span class='clg'>" + Category + "</span>";
   text2 += "<span class='clear'></span>";
   text2 += "</div>";
 
   $("allbody").insertAdjacentHTML("beforeEnd",text2);
   count++;
}

//******************************************************************

window.onload = function(){
   getlist_html = $("allbody").innerHTML;
   Listening();
   getUpdate();
};

//******************************************************************
//*********************进入VBScript域*******************************
//******************************************************************
</script>
<script language="vbscript" type="text/vbscript">
dim dbpath,fso,textObj,conn,rs,connstr

function str2asc(strstr)
   str2asc = hex(asc(strstr))
end function

'//**********************功能函数区*********************************

'-----------------------------------------------------------------
Function getHTTPPage(Path)
   t = GetBody(Path)
   getHTTPPage=BytesToBstr(t,"GB2312")
End function

Function GetBody(url)
   Set vbXml = CreateObject("Microsoft.XMLHTTP")
   With vbXml
    .Open "Get", url, False, "", ""
    .Send
    if .readystate<>4 then
     GetBody = ""
    else
     GetBody = .ResponseBody
    end if
   End With
   Set vbXml = Nothing
 
   If Err.number<>0 then
    Response.Write "服务器获取文件内容出错,请稍后再试!!!"
   Err.Clear
   End If
End Function

Function BytesToBstr(bodys,Cset)
   dim objstream
   set objstream = CreateObject("adodb.stream")
   objstream.Type = 1
   objstream.Mode =3
   objstream.Open
   objstream.Write bodys
   objstream.Position = 0
   objstream.Type = 2
   objstream.Charset = Cset
   BytesToBstr = objstream.ReadText
   objstream.Close
   set objstream = nothing
End Function

'-----------------------------------------------------------------
function DownUpdate(UpdateUrl)
 
   text = getHTTPPage(UpdateUrl)
 
   set textObj=fso.CreateTextFile("dohi.update.hta",2,true)
   textObj.writeLine(text)
   textObj.close
   msgbox "升级成功!新版本为目录下的dohi.update.hta"
   window.close
end function

Function mydate(dat)
   if InStr(dat,"+0800")<>0 then
    dat=mid(dat,6,20)
   end if
   dat=replace(dat,"P.M.","PM")
   dat=replace(dat,"星期一","")
   dat=replace(dat,"星期二","")
   dat=replace(dat,"星期三","")
   dat=replace(dat,"星期四","")
   dat=replace(dat,"星期五","")
   dat=replace(dat,"星期六","")
   dat=replace(dat,"星期日","")
   dat=cdate(dat)
   mydate=dat
end function

sub window_onload()
   dbpath = "monyer.mdb"
   set fso = CreateObject("Scripting.FileSystemObject")
 
   if fso.FileExists(dbpath) then
    'msgbox("数据库存在,更新将采取数据追加方式")
   else
    Set conn = CreateObject("ADOX.Catalog")
    conn.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&dbpath)
 
    Set rs = CreateObject("adox.table")
    rs.Name = "Blog"
    rs.columns.append "Name", 202
    rs.columns.append "Url", 202
    rs.columns.append "Content", 203
    rs.columns.append "Category", 202
    rs.columns.append "Date", 7
    rs.columns.append "User", 202
    conn.tables.append rs
 
    set rs = nothing
    set conn = nothing
   end if
 
   connstr = "provider=microsoft.jet.oledb.4.0;data source=" & dbpath
   Set conn = CreateObject("adodb.connection")
   conn.Open connstr
 
end sub

'//********************数据库调用***********************************

function add(Name,Url,Category,pubDate,UserName) '增
   Set rs = CreateObject("adodb.recordset")
   sql = "select Name,Url,Content,Category,Date,User from blog where Url='"&Url&"'"
   rs.Open sql, conn, 1, 3
    if rs.eof then
     rs.addnew
      rs("Name") = Name
      rs("Url") = Url
      rs("Content") = "null"
      rs("Category") = Category
      rs("Date") = mydate(pubDate)
      rs("User") = UserName
     rs.update
    end if
   rs.close
   set rs = nothing
end function

function addArt(Content)
   Set rs = CreateObject("adodb.recordset")
   sql = "select Url,Content from blog where Url='"&Url&"'"
   rs.Open sql, conn, 1, 3
    if not rs.eof then
     rs("Content") = Content
     rs.update
    end if
   rs.close
   set rs = nothing
end function

function viewList()
   Set rs = CreateObject("adodb.recordset")
   sql = "select Name,Url,Content,Category,Date,User from blog order by date desc"
   rs.Open sql, conn, 1, 1
    while not rs.eof
     call showList(rs("Name"),rs("Url"),rs("Content"),rs("Category"),rs("Date"),rs("User"))
     rs.movenext
    wend
   rs.close
   set rs = nothing
end function

'//*****************************************************************
function getArt()
   Set rs = CreateObject("adodb.recordset")
   sql = "select Name,Url,User,Content from blog order by date desc"
   rs.Open sql, conn, 1, 3
   getEveryArt()
end function

function getEveryArt()
   if rs.eof then
    call getArticle(0,0,0)
    rs.close
    set rs = nothing
   elseif rs("Content")<>"null" then
    rs.movenext
    getEveryArt()
   else
    call getArticle(rs("Name"),rs("Url"),rs("User"))
   end if
end function

function saveArt(Content)
   rs("Content") = Content
   rs.update
   rs.movenext
end function
'************************************************

function del() '删
   Set rs = CreateObject("adodb.recordset")
   sql = "select * from blog"
   rs.Open sql, conn, 1, 3
 
   rs.close
   set rs = nothing
end function

function search() '查
   Set rs = CreateObject("adodb.recordset")
   sql = "select * from blog"
   rs.Open sql, conn, 1, 3
 
   rs.close
   set rs = nothing
end function

function change() '改
   Set rs = CreateObject("adodb.recordset")
   sql = "select * from blog"
   rs.Open sql, conn, 1, 3
 
   rs.close
   set rs = nothing
end function

</script>
<body>
<div id="menu">
<input name="b_getlist" type="button" id="b_getlist" value="获取列表" />
<input name="b_getart" type="button" id="b_getart" value="获取文章" />
<input name="b_viewList" type="button" id="b_viewList" value="查看列表" />
<input name="b_search" type="button" id="b_search" style="display:none" value="内容搜索" />
</div>

<div id="allbody">
<div id="head">
  http://hi.baidu.com/<input name="blogurl" type="text" id="blogurl" value="monyer" />
   <input name="initialize" type="button" id="initialize" value="初始化" />
</div>
<br/>
<div id="choose">
   开始页
   <select name="page_min" id="page_min">
   </select>
   结束页
   <select name="page_max" id="page_max">
   </select><br />
 
   按分类提取?
   <input name="isArtclg" type="checkbox" id="isArtclg" value="checkbox" />
   <select name="artclg" id="artclg">
   </select><br />
   <input name="getList" type="button" id="getList" value="提取文章列表" />
</div>
<br/>
<div id="list">
</div>
<br/>
<div id="error">
   因网络问题,未获取的url列表:<br />
</div>
</div>

</body>
</html>

欢迎评论交流,但万万请某些人不要剽窃我的东西才好,我的MonyerJS已经有了前车之鉴(甚至有拿去赚稿费的)。不要总是我为了将就大家,用脚本编代码,大家就不将就我,各种权利侵犯。用其他语言我并不是编不出东西来,所以还请手下留情。吃蛋不杀下蛋鸡,否则以后我可能会失去这种主动性。谢谢!还望海涵!

大家有任何问题,还望及时反馈,谢谢!

Monyer !