軟體開發,創意是靈魂——用HttpWebRequest和正規表示式提取網頁中的連結

asword發表於2007-03-14
提取網頁連結有什麼用?比如,你可以做網頁地址蒐集器,郵件地址蒐集器,圖片或Flash蒐集器等等。如何用最高效快捷的方式提取網頁中的連結地址,這正是本文所要探討的。[@more@]提 取網頁連結地址有多種方式。在VS.NET開發環境下,總的是透過兩種方式:
   一.用AxWebBrowser控制元件。等網頁載入完,然後提取其中的連結。
   二.不用AxWebBrowser控制元件的方式,先取得網頁原始碼,然後提取其中的連結。
   本人早先是用第一種方式,第一種方式要先等網頁載入完畢,瀏覽器會下載許多無關的內容,速度較慢。因此,推薦用本文介紹的方式,用HttpWebRequest結合正規表示式取得網頁中的連結。
   本文分以下幾個步驟:
   用HttpWebRequest取得網頁原始碼
   用正規表示式取得連結地址
   去除重複地址
   儲存為XML

用HttpWebRequest取得網頁原始碼


Dim url As String=" " ' 這是tuenhai的小站,有空來坐坐
Dim httpReq As System.Net.HttpWebRequest  
Dim httpResp As System.Net.HttpWebResponse
Dim httpURL As New System.Uri(url)
httpReq = CType(WebRequest.Create(httpURL), HttpWebRequest)
httpReq.Method = "GET"
httpResp = CType(httpReq.GetResponse(), HttpWebResponse)
httpReq.KeepAlive = False ' 獲取或設定一個值,該值指示是否與 Internet 資源建立持久連線。

Dim reader As StreamReader = _
New StreamReader(httpResp.GetResponseStream, System.Text.Encoding.GetEncoding("GB2312"))
Dim respHTML As String = reader.ReadToEnd() 'respHTML就是網頁原始碼


  是不是很簡單?
   對於概念的理解,在MSDN中有極詳細的介紹,請在VS.NET 2003中點選“幫助”,再點選“搜尋”,然後輸入類名,如HttpWebRequest,一回車,就什麼資料都有了。對於下面碰到的程式設計概念,如有不理解的,也請先搜尋MSDN,不再重複說明。


用正規表示式取得連結地址

Dim strRegex As String = "http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?" '這就是表示式
Dim r As System.Text.RegularExpressions.Regex
Dim m As System.Text.RegularExpressions.MatchCollection
r = New System.Text.RegularExpressions.Regex(strRegex, System.Text.RegularExpressions.RegexOptions.IgnoreCase)   
m = r.Matches(respHTML)
Dim i As Integer
For i = 0 To m.Count - 1
     form1.DefInstance.ListBox1.Items.Add(m(i).Value) 'form1.DefInstance是form1的共享屬性和例項
Next i  
form1.DefInstance.ListBox.Visible = True ' 設定ListBox為可見
form1.DefInstance.ListBox.Sorted = True ' 對ListBox各元素進行排序



form1.DefInstance.ListBox1.Items.Add(m(i).Value) 'form1.DefInstance是form1的共享屬性和例項, 共享成員如果是方法或屬性,我們不用建立例項就可以直接用‘類名 .共享成員'的方法進行呼叫。設定方法如下:

Private Shared m_vb6FormDefInstance As form1
Public Shared Property DefInstance() As form1
   Get
     If m_vb6FormDefInstance Is Nothing OrElse m_vb6FormDefInstance.IsDisposed Then '判斷窗體例項是否存在
       m_vb6FormDefInstance = New form1
     End If
     DefInstance = m_vb6FormDefInstance
   End Get
   Set(ByVal Value As form1)
     m_vb6FormDefInstance = Value
   End Set
End Property






去除重複地址


Dim countForms As Integer '以下程式碼去除重複地址
Dim lstForms() As String
Dim CurId As Integer
With formBrow.DefInstance.ListBox1
   ReDim Preserve lstForms(0)
   lstForms(0) = .Items(0) '新陣列的第一項和list的第一項相同
   For countForms = 1 To .Items.Count - 1 'items.count得到list1中的專案數
     CurId = UBound(lstForms) 'curid為newlist中有專案數
     If .Items(countForms) <> lstForms(CurId) Then '如果舊錶第二項不等於新表最大項
       ReDim Preserve lstForms(CurId + 1) '定位到新表第二項
       lstForms(CurId + 1) = .Items(countForms) '新表第二項等於舊錶第二項
     End If
   Next countForms
   .Ite ms.Clear() '刪除舊錶所有項
   For countForms = 0 To UBound(lstForms) '把新表寫入舊錶
     .Items.Add(lstForms(countForms))
   Next countForms
End With




            把地址匯出為XML

可擴充套件標記語言 (XML) 是一種提供資料描述格式的標記語言。該語言使跨越多個平臺進行更準確的內容宣告和獲得更有意義的搜尋結果變得更加容易。此外,XML 實現了表示與資料的分離。例如,在 HTML 中,使用標記來告訴瀏覽器將資料顯示為粗體或斜體;而在 XML 中,標記只用於描述資料,例如城市名、溫度和大氣壓。在 XML 中,使用樣式表(例如,可擴充套件樣式表語言 (XSL) 和層疊樣式表 (CSS))在瀏覽器中顯示資料。XML 使資料與表示及處理分離開來,透過應用不同的樣式表和應用程式,使您能夠根據需要顯示和處理資料。

  XML 是為在 Web 上傳送而進行最佳化了的 SGML 的子集。它是由全球資訊網聯合會 (W3C) 定義的。該標準化確保了結構化資料的統一性和相對於應用或供應商的獨立性。

  XML 是 Visual Studio .NET 和 .NET Framework 的很多功能的核心。XML 是可用於許多不同應用程式的格式,我們可將蒐集到的連結儲存為XML。
XmlTextWriter 是 XmlWriter 類的實現,該類提供將 XML 寫入檔案、流或 TextWriter 的 API。該類有許多驗證和檢查規則,以確保所編寫的 XML 的格式正確。當與某些規則發生衝突時,將會引發異常,並且這些異常應該被捕獲。XmlTextWriter 有不同的建構函式,每個函式指定寫入 XML 資料的不同型別的位置。下面程式碼使用的是將 XML 寫入檔案的建構函式。
   首先使用 Formatting 屬性指定正被編寫的 XML 資料的格式。透過將此屬性設定為 Indented,編寫器使用 Indentation 和 IndentChar 屬性縮排子元素。
   程式碼顯示了與每個 XML 節點型別相對應的 XML 編寫方法。例如,編寫一個元素將呼叫 WriteElementString 方法,編寫一個屬性將呼叫 WriteAttributeString 方法。對於巢狀級別,可以使用 WriteStartElement/WriteEndElement 對;如果要建立較複雜的屬性,則可以使用 WriteStartAttribute/WriteEndAttribute 對。
請注意程式碼如何使用 WriteStartDocument 方法編寫帶版本號“1.0”的 XML 宣告。如果要讓編寫器檢查該文件的格式是否正確(先是 XML 宣告,序言中的 DOCTYPE,只有一個根級別元素,等等),您必須在呼叫任何其他編寫方法之前,呼叫此可選的 WriteStartDocument 方法。接著,此程式碼呼叫 WriteDocType 方法編寫名為“urls”的文件型別。WriteDocType 呼叫中的第三個引數指定編寫器將編寫 SYSTEM“urls.dtd”。編寫完成後,XML 檔案指示有一個要根據其進行驗證的外部 DTD。

  最後,程式碼呼叫 Flush 方法將 XML 資料儲存到檔案,然後才呼叫 Close 方法。(雖然此示例確實只需要 Close 方法,但是也存在這樣的情況,即需要儲存所生成的 XML,並且需要重複使用編寫器。)

  要檢查 XmlTextWriter 的輸出,可透過用 XmlTextReader 讀取生成的檔案來執行往返測試,以驗證 XML 的格式是正確的。

Private Sub saveXml()
   Dim saveFileDialog1 As New SaveFileDialog
   saveFileDialog1.Filter = "xml|*.xml"
   saveFileDialog1.Title = "Save a xml File"
   saveFileDialog1.ShowDialog()
   If saveFileDialog1.FileName <> "" Then  '如果檔名不等於空白
     Dim fileName As String = saveFileDialog1.FileName  
     If Not System.IO.File.Exists(fileName) Then  '如果不存在同名檔案
      Dim myXmlTextWriter As XmlTextWriter = New XmlTextWriter(fileName, Nothing)
       myXmlTextWriter.Formatting = System.Xml.Formatting.Indented  '設定縮排
       myXmlTextWriter.WriteStartDocument(False)
       myXmlTextWriter.WriteDocType("urls", Nothing, "urls.dtd", Nothing)
       myXmlTextWriter.WriteComment("This file save the Urls")  '註釋
       myXmlTextWriter.WriteStartElement("urls")      '開始元素
       myXmlTextWriter.WriteStartElement("url1", Nothing)  '開始元素
       myXmlTextWriter.WriteAttributeString("now", Now)   '在屬性裡記錄時間
       For countAll As Integer = 0 To ListBox1.Items.Count - 1
         Dim title As String = Strings.Right(ListBox1.Items.Item(countAll), 3)  '取URL後三字
         Dim body As String = lstMuLu.Items.Item(countAll)       
         myXmlTextWriter.WriteElementString(title, Nothing, body)
       Next
       myXmlTextWriter.WriteEndElement()   
       myXmlTextWriter.WriteEndElement()

      'Write the XML to file and close the myXmlTextWriter
       myXmlTextWriter.Flush()
       myXmlTextWriter.Close()

     End  If
   End If
End Sub



軟體開發,創意是靈魂

在軟體開發實踐中,真正讓我們感到貧乏的,永遠不會是技術,而是創意。
   創意,是軟體開發的靈魂。
   隨著開發工具的升級,進化,軟體開發越來越象搭積木。我們更多的是學習開發工具的使用,而不是自己編寫底層程式碼——許多底層程式碼,開發工具已經為我們代勞了。
這麼說並不是tuenhai對軟體開發有多精通。事實上,tuenhai從2003年10月開始自學程式設計(VB6),11月轉到VS.NET。2004年1月,完成tuenhai的第一個軟體 AdKing 。
只要學習方法得當,掌握技術並不是難事。這在tuenhai的第一篇VS.NET文章 《VS.NET學習方法論》 中有所論述。
   每個搞軟體開發的人不妨自問一下(自然包括tuenhai了),自己在軟體開發中的創意如何?你能保證透過你的創意已經把你所掌握的技術發揮得淋漓盡致了嗎?你在每天大量編寫CODE的同時,有多少時間用於思考創意?

以本文程式碼舉例,發揮您的創意,可以編寫多少個應用軟體?
   這麼說,並不是要您編寫多少個應用軟體。
   您能列出大量軟體專案、方案,自然能從中挑選出適合您的最佳方案。
   一即是多。
   磨刀不誤砍柴工。
   以《 用正規表示式取得連結地址 》為例,只要靈活改變strRegex表示式的值,我們可以從網頁原始碼中任意提取我們想要的東東。如果你要開發郵件地址蒐集器,strRegex = " [w-]+@([w-]+.)+[w-]+ " 即可。如果要蒐集Flash呢?
   如果您能列出50種方案,請來信告訴tuenhai。如果你列出的方案比tuenhai多,I fu le u,tuenhai拜您為師。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/82387/viewspace-904997/,如需轉載,請註明出處,否則將追究法律責任。

相關文章