程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# HTML解析示例---星星引發的血案

C# HTML解析示例---星星引發的血案

編輯:C#入門知識

【前言】  

    從CSDN轉投cnBlog也有一段時間了,發現cnBlog中也有類似CSDN的迷你博客的功能,就是閃存。閃存使用了幸運星的機制也引發一大批人沒事就來刷星星……雖然不知道有什麼用,但無聊中也試過幾次。由於幸運星隨機分發,那麼就有一個想法,不停的發消息,不是星星的就刪掉以免有刷屏嫌疑。手動操作起來當然怪麻煩的,於是干脆用代碼,這就產生了一個需求:獲取html,解析,自動提交登陸,自動發布,判斷是否是星星,刪除等等。

【方案】Webbrowser

      因為只是想隨手玩下,沒考慮復雜性和完善程度,我最先想到的是用webbrowser,然後獲取html,純手動解析。

      Step1:表單填充

      首先當然是放置一個Webbrowser控件,為了方便,直接設置了url為http://passport.cnblogs.com/login.aspx

      然後登陸http://passport.cnblogs.com/login.aspx,查看源代碼獲取登陸框的id。

 

 

 

            HtmlDocument doc = (HtmlElement em  str =   = 

      如果登陸成功,頁面應該跳轉至主頁,程序也需要導航到閃存的網址http://home.cnblogs.com/ing,如果未成功則還是停留在該頁面,所以通過判斷webbrowser的當前url就可以知道是否登陸成功了,這是一個取巧的方法。當然,判斷當前url也需要在DocumentCompleted事件中,因為我們需要等待頁面刷新結束後才能做判斷。

            isLogIn =  (wbBlog.Url.ToString() == = 

      這時候可能會發現DocumentCompleted事件中需要做的事有點多了,會不會有沖突或者重復執行?所以我們需要一些標記來控制。在上面的代碼中可以看到isLogIn這個變量,就是用於控制在DocumentCompleted到底要執行判斷還是執行表格填充。

       Step2:發布閃存

       登陸成功後,webbrowser跳轉到閃存頁面,這時候需要程序自動發布閃存,原理也是表單填充和提交。可以看下頁面的源碼。

你在做什麼?你在想什麼?

      

        然後程序需要做的就是不停的做填充和提交,然後判斷是否有星星,如果有就退出循環。

            HtmlDocument doc = (HtmlElement em  str = = = =

       提交表單後,頁面會刷新,所以判斷是否有星星也是要在DocumentCompleted事件中,同時需要isPulish這個標記來表示是否需要執行判斷方法。

       Step3:判斷是否有星

       分析閃存頁面的源碼可以看到每一條閃存的html都是下面這樣:

作者: 內容 31分鐘前 回應

        所以首先要獲取id格式是feed_content_***的所有div,然後判斷這個htmlelement中是否包含了自己發布的信息,如果是就鎖定這個element,然後判斷是否包含

<img src="http://www.bkjia.com/uploads/allimg/131115/145H31629-0.png" class="ing_icon_lucky" alt="" title="這是幸運閃"/>

      如果有,則提示發布成功,如果沒有則刪除這條閃存並繼續發布。需要注意的是,發布一條新的閃存後並沒有刪除選項,

                                                                               

      需要刷新一下頁面才會看到,包括查看是否有星星也是要刷新後才能判斷。

             HtmlDocument doc = (HtmlElement em  str = (str !=  && str.Contains() && (em.OuterHtml.Contains( +

       Step4:刪除閃存

      程序寫到這裡我遇到了麻煩,由於我是獲取id是feed_content_***的div,現在要取得div中的刪除鏈接,發現這個a鏈接沒有id,那該如何獲取?貌似需要用正則表達式了。但這裡偷了個懶,獲取頁面所有的a連接,然後判斷title屬性是不是為“刪除這個閃存”,從而獲取這個a連接元素。



        得到a連接的元素之後就可以操作它的Click事件了,但又有一個新問題,點擊刪除之後,這貨居然彈出一個Confirm對話框,繼而引出一個老問題,如何干掉網頁彈出的Confirm和Alert對話框。這裡使用一個原始方法,讓頁面所有的function confirm()都自動返回ture。首先需要引用Microsoft.mshtml和Interop.SHDocVw,具體操作代碼如下:

                                HtmlElementCollection hrefs = em.GetElementsByTagName( (HtmlElement h  (h.GetAttribute() == = (wbBlog.ActiveXInstance  SHDocVw.WebBrowser).Document , 
                                        

         做到這一步,基本功能已經實現,現在需要做的就是在發布,判斷和刪除這幾個操作中做循環,需要注意的是網頁頁面上的刷新和刪除閃存是通過ajax刷新部分div,所以webbrowser不會觸發DocumentCompleted事件,這裡可以仿照winform寫一個DoEvent,還需要Sleep一段時間。然後才能讀取刷新後的頁面信息。

         =   ExitFrame(=  

【結束】

      到這裡程序就寫完了,運行一下,發現程序在不停的控制發布和刪除,但還是有問題,刷不到星星。cnblog的星星雖說是隨機分配,但是相同的內容,或者相隔時間太短都會被排除,閃存還有兩個機制,同一頁面只允許一個用戶發布五條信息,用戶每天發布閃存的數量是有上限的,具體多少沒有統計,是用程序刷了幾百條後給出的提示。所以程序雖然寫完了,但卻沒有達到最初的效果,這不禁讓人失望。不過換一種思路,一次發布五條不同的閃存(需前後有數秒間隔),然後依次判斷是否有星星,刪除沒有星星的,保留有星星的,這樣應該就符合規則了。當然,本來是隨手寫寫的東西發現還是挺復雜的,這部分就沒有再實現了。其實這篇文章的主要目的是HTML解析不是麼?

                   

      回過頭來想想,如果真的要做這樣一個工具,用webbrowser做html解析會導致程序的可維護性和執行效率很低,如果是解析html,推薦使用Html Agility Pack,而提交刪除等操作則可以用網頁開發工具抓個包分析然後用ajax直接發送請求。舉個栗子,在之前的代碼中,我們要獲取閃存的div以及閃存的內容並判斷是否有星星等操作是比較復雜的,如果使用Html Agility Pack,Xpath將輕松搞定一切。

             pageUrl = = [] pageSourceBytes = wc.DownloadData( pageSource = Encoding.GetEncoding(=  xpath = = (HtmlNode node = node.SelectSingleNode( (img != 

      最後附上程序源碼,有興趣的可以重構一下程序,完成未實現的功能部分。

源碼下載

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved