自己用javascript寫了一些代碼,用來批量下載“絕影”博客上《瘋狂的程序員》文章...

近日,在拜讀了“絕影”博客上《瘋狂的程序員》連載文章後,感觸頗深,從他的文章裏找了自己的人生記憶,彷彿其中的主角就是自已…..

可是,由於白天要上班,晚上回家了也很晚,沒多少空閒時間看,想來想去,最後決定將文章下下來,做成txt格式放到手機上看,反正每天上下班都有差不多兩個小時,夠我看的了。

問題來了,如果我是用手工的方式去一頁一頁的複製、粘貼。。。這工作量是不是也太大了,況且自己還身爲一名“程序員”,感覺總有點怪怪的。又不想上網找那種可以下載網頁的軟件。最後想想,反正這難度應該不大,自己動手寫個小程序試試,不成功也就當是練習練習吧。

接下來,開始分析需求。其實很簡單,就是輸入博客的網址,然後得到當前頁面當中的所有文章的超鏈接,再根據這個鏈接去讀取每篇文章的內容,把內容全部顯示到一個網頁裏,然後就只需要複製一次就可以將所有的內容copy下來了。

 

開始寫代碼,這裏碰到了一個問題,本想一次性將所有的鏈接全部得到,然後通過循環的方式去讀取每個鏈接所對應的網頁內容。可是當我真正去實現的時候出現了一個無法訪問的錯誤,打開了一個CSDN用戶登錄頁面。不知道是什麼原因,猜想是人家網站不讓你這樣去弄吧,也沒多想。此路不行,換條路。打開其中的一個鏈接,看了一下結構,發現每篇文章上面都有一個鏈接可以查看下一篇文章的內容,既然如此那我就可以通過讀取這個鏈接得到下一篇文章的網頁了。通過不斷的循環,應該可以一直不斷的得到後面的網頁。

 

思路理清了,就開始寫代碼吧

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        //獲取網頁內容,經過處理後將內容寫入到指定的div當中
        function getPage(url){
            var xmlhttp = createXmlHttp();                      //獲取xmlhttp對象
            var all_yk = document.getElementById("all_yk");    //得到用於保存網頁的div
            if(url == null || url == "") {
                alert("網址不能爲空!");
                return;
            }else {
                xmlhttp.open("GET",url,false);
                xmlhttp.send();
                if(xmlhttp.readyState ==4) {
                    if(xmlhttp.status != 200) {
                        alert("連接失敗!");
                        return;
                    }else {
                        /*
                            這裏通過xmlhttp對象讀取了網頁後,將內容寫入到all_yk這個div當中,
                            這裏面的內容其實就是包含所有內容的網頁源代碼。
                            由於div的樣式已設置不顯示,所以我們在網頁是看不到的。
                         */
                        all_yk.innerHTML=xmlhttp.responseText;
                        //這個用來提取我們需要數據,獲取文章的內容就看它了
                        getText();
                    }
                }
            }
        }

        //定義一個計數器,通過此計數器,我們可以設置要訪問的級數
        var count=1;
        //從指定的div當中獲取需要的數據
        function getText() {
            var temp_yk = document.getElementById("temp_yk");
            //下一頁的超鏈接
            var nextHREF;
            if(document.getElementById("Post.ascx_ViewPost_PreviousAndNextEntriesUp")){
                /*
                    這裏的id是通過分析網頁源代碼得到的,大家可以自己去查看博客上的網頁源代碼就知道了
                    得到了這個節點對象我們就可以縮小查找範圍,只需要得到這個節點的第一個<a>元素的href屬性
                    就可以獲取下一篇文章的鏈接了,再將鏈接保存到變量當中,用於下一次getPage()方法的運行,
                    如此循環即可以不斷的得到不同的文章內容
                 */
                 var nextURLS =document.getElementById("Post.ascx_ViewPost_PreviousAndNextEntriesUp");
                    nextHREF=nextURLS.getElementsByTagName("a")[0].getAttribute("href");
            }

            /*
             *這段代碼用來獲取我們需要的文章內容,同樣通過分析源代碼,所有的文章內容都位於一個id=csdnblog_content
              的div節點當中,我們只需要判斷一下這個div是否存在,就知道有沒有文章內容了。同理,再分析源碼得知所有的文章每一段
               都位於一個<p>節點當中,而且這個<p>節點都一個相同的class屬性,既然如此,那麼我們可以通過獲取當前頁面當中的所有
               <p>節點,然後循環這個集合,判斷其中的每一個節點的class屬性是否等於“MsoNormal”,就可以得到文章的具體內容。
               最後將每一段內容添加到temp_yk這個div節點當中。如此循環就可以將我們需要的內容獲取到了。
             */
            if(document.getElementById("csdnblog_content")){
                var allP = document.getElementsByTagName("p");
                for(var i=0;i<allP.length;i++) {
                    if(allP[i].className=="MsoNormal") {
                        temp_yk.innerHTML+=allP[i].innerHTML+"<br>";
                    }
                }
            }

            /*
                由於鏈接比較多,而且讀取網頁的速度不是很快,同時爲避免出現假死機的現象,
                我們在這裏設置了讀取網頁級數的數量。這個數量指的是從當前網頁算起,向下
                讀取多少次的數量。如本文是10,如果我是從第一章開始,則在讀完了第10章後,
                程序不在運行
             */

            if(count <10) {
                  count++;
                //我們可以在這裏設置一個標識,用來區分每一章的內容(可要,可不要)
                temp_yk.innerHTML+="**********************<p>";
                 getPage(nextHREF);
             }

        }

        //獲取所有超鏈接
        function getAllHref(){
            var url = document.getElementById("url").value;
            getPage(url);   //讀取當前頁面當中的所有內容,然後進行分析
            var all_yk = document.getElementById("all_yk");
            var book_contents = document.getElementById("book-contents").innerHTML;
            all_yk.innerHTML=book_contents;
            var as =document.getElementsByTagName("a");
            for(var i=0;i<10;i++) {
                var nextUrl =as[i].getAttribute("href");
                getPage(nextUrl);
            }
        }

        function clearURL() {
            document.forms["getText"].reset();
            document.getElementById("all_yk").innerHTML="";
            //查看動態生成的源代碼
            //document.write(document.documentElement.outerHTML);
        }

        //創建xmlhttp對象
        function createXmlHttp() {
{          var xhr;
            if (window.ActiveXObject)   // IE下創建XMLHTTPREQUEST
            {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if (window.XMLHttpRequest)   // 其他瀏覽器創建XMLHTTPREQUEST
            {
                xhr = new XMLHttpRequest();
            }
            return xhr;
        }

}
    </script>

</head>
<body style="font-size:12px;">
<form action="test.html" name="getText">
<table align="center">
    <tr>
        <td>請輸入要讀取的網址:</td>
    </tr>
    <tr>
        <td><input type="text" id="url" size="90" name="url"><a href="#" οnclick="getPage(url.value)" >讀取</a>
            <input type="button" value="清空" οnclick="clearURL()" id="clear"/></td>
    </tr>

</table> </form>
<!--用於臨時保存網頁內容,id名字沒取好-->
<div id="all_yk" style="display:none;"></div>
<!--用於保存最後的結果內容,id名字沒取好-->
<div id="temp_yk" style="display:block;"></div>
<!--臨時保存下一篇文章的超鏈接-->
<div id="a_yk" style="display:none;"></div>

</body>

</html>

 

弄個效果圖:



 

最後說明一下,附件當中的內容只有一個網頁,直接使用IE打開即可,fireFox可能支持不太好。注意:不可以將此網頁部署到一個web項目當中去運行。原因是:瀏覽器限制了javascript的跨域訪問。另外,如果設置的級數過長,或者網速比較慢,程序運行的速度會慢一點,請耐心等待一會。

附上“絕影”的博客:http://crazypro.hi.csdn.net/ 這本書還是不錯,值得我們當程序員的看看

 

 

注:我現在只是一個菜鳥,還望高手多指點一二。謝謝!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章