thongkorn โพสต์ 2018-10-31 17:54:49

[VB.NET] การดึงข้อมูลจากหน้าเว็บเพจ ด้วยการอ่านค่า HTML Tag

http://www.g2gnet.com/webboard/images/vbnet/html2datagridview.png

โปรเจคนี้จัดว่าเป็นลักษณะพื้นฐานในกระบวนการคิดแก้ปัญหา เพราะแอดมินจะนำเสนอวิธีการใช้คำสั่งง่ายๆ ที่ทุกๆภาษาแทบจะต้องมีอยู่แล้ว โดยไม่พึ่งพาความเก่งหรือเทคโนโลยีใหม่ๆแต่ประการใด สำหรับงานนี้เราต้องใช้ความรู้ทั้งด้านการเขียนโปรแกรม และความรู้ในเรื่องการอ่าน Tag ของเอกสาร HTML แต่แอดมินจะขอลัดขั้นตอนนี้ไปนะครับ หากใครไม่รู้ก็ต้องไปศึกษาหาข้อมูลเองก็แล้วกันครับพี่น้อง ...

กระบวนการคิด คือ ให้นำเว็บเพจมาแสดงผลใน WebBrowser Control จากนั้นเอาเอกสาร หรือที่เราเรียกกันว่า HTML TAG ของเว็บเพจมาเก็บไว้ใน RichTextBox Control (ซึ่งปกติตัวนี้เราจะต้องซ่อนการมองเห็นของ Users) จากนั้นทำการค้นหาคำ (Instr = In String) ที่ต้องการ แล้วเลือกออกมาตามแพทเทิร์นของผู้จัดทำเว็บเพจ เพื่อทำการแยกแยะข้อมูล (Parser) ตามที่เราต้องการ ... สรุปรวม เราแค่โหลดเอกสาร HTML มาเท่านั้น และตัดข้อความเฉพาะในส่วนที่คาดหมายหรือต้องการ แล้วทำการแยกข้อมูลออกมา ในลักษณะที่เหมือนกับชุดข้อความทั่วๆไป ...

ลักษณะข้อมูลที่นำมาใช้เพื่อทำการแยกแยะ ซึ่งเราควรจะนำมาหลายๆชุดเพื่อทำการเปรียบเทียบหาความเหมือน และความต่าง
หน่อไม้ฝรั่ง(เขียว)
<TD class=Tb_Hprice01 width=40>ม.ค. </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>156.45 </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>240.00 </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>120.00 </TD>

กุ้ยช่ายขาว
<TD class=Tb_Hprice01 width=40>ม.ค. </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>114.84 </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>130.00 </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>100.00 </TD>

ผักกวางตุ้งธรรมดา
<TD class=Tb_Hprice01 width=40>ม.ค. </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>9.92 </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>20.00 </TD>
<TD class=Tb_cntHP01_02 width=70 align=center>2.00 </TD>
โค้ดตัวหลักในการแยกแยะข้อมูลออกจากชุดตัวอักษรธรรมดา ... จะเป็นโปรแกรมย่อย เพราะมันมีรอบการทำงาน 12 เดือนที่ซ้ำๆกัน
    ' / --------------------------------------------------------------------------
    Private Sub ExtractData(ByVal MyMonth As String, ByVal MyYear As Integer, ByVal PlantName As String)
      Dim iStart As Long
      Dim iArr(4) As String
      Dim tmp As String
      If RichTextBox1.Text.Length = 0 Then Return
      '// เริ่มต้นอ่านชุดราคาตัวแรกเป็น ราคาเฉลี่ย ... โดยเริ่มนับจากชื่อแรกของเดือน และนับเผื่อไปอีก 195 ตัว
      iStart = InStr(RichTextBox1.Text, MyMonth)
      tmp = Mid(RichTextBox1.Text, iStart, 195)
      '// จะได้--> "ม.ค. </TD><TD class=Tb_cntHP01_02 width=70 align=center>156.45 </TD><TD class=Tb_cntHP01_02 width=70 align=center>240.00 </TD><TD class=Tb_cntHP01_02 width=70 align=center>120.00 </TD><TD"

      tmp = tmp.Replace("<TD class=Tb_cntHP01_02 width=70 align=center>", "")
      '// ให้ตัดคำซ้ำออกไปก็จะเหลือ
      '//--> "ม.ค. </TD>156.45 </TD>240.00 </TD>120.00 </TD><TD"
      '// แยกชุดข้อมูลออกจากกันด้วย </td> ทำให้
      iArr = Split(tmp.ToLower, "</td>")
      '// iArr(0) = ชื่อเดือน
      '// iArr(1) = "156.45 " <-- ราคาเฉลี่ย
      '// iArr(2) = "240.00 " <-- ราคาสูงสุด
      '// iArr(3) = "120.00 " <-- ราคาต่ำสุด
      Dim row As String() = New String() {Trim(iArr(0)), MyYear, PlantName, Trim(iArr(1)), Trim(iArr(2)), Trim(iArr(3))}
      dgvData.Rows.Add(row)
    End Sub
มาดูโค้ดแบบฉบับเต็ม ...
' / --------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand)
' / Facebook: https://www.facebook.com/commonindy (Worldwide)
' / Purpose: Read HTML Tag from RichTextBox and get some data into DataGridView.
' / Microsoft Visual Basic .NET (2010)
' /
' / This is open source code under @CopyLeft by Thongkorn Tubtimkrob.
' / You can modify and/or distribute without to inform the developer.
' / --------------------------------------------------------------------------

Public Class frmHtml2DataGrid

    ' / --------------------------------------------------------------------------
    Private Sub btnLook_Click(sender As System.Object, e As System.EventArgs) Handles btnLook.Click
      If Trim(txtWebAddress.Text) = "" Then Return
      WebBrowser1.Navigate(txtWebAddress.Text)
    End Sub

    ' / --------------------------------------------------------------------------
    Private Sub frmHtml2DataGrid_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      '// Sample
      txtWebAddress.Text = "http://www.taladsimummuang.com/dmma/Portals/PriceListItem.aspx?id=010131020"
      '// แสดงผล Web Address บน WebBrowser
      If Trim(txtWebAddress.Text) <> "" Then Call btnLook_Click(sender, e)
      '//
      Call InitializeGrid()
    End Sub

    ' / --------------------------------------------------------------------------
    Private Sub btnRead_Click(sender As System.Object, e As System.EventArgs) Handles btnRead.Click
      '// เคลียร์ค่าใน RichTextBox
      RichTextBox1.Clear()
      '// รับค่าเอกสาร HTML TAG ที่อยู่ใน WebBrowser
      RichTextBox1.Text = WebBrowser1.Document.Body.InnerHtml
      If RichTextBox1.Text.Length = 0 Then Return
      '// อ่าน TAG เข้าสู่ตารางกริด
      Call DataWeb2Grid()

      '// เลื่อนแท็ปไปตัวที่ 3 เพื่อแสดงผลข้อม฿ลในตารางกริด
      TabControl1.SelectedIndex = 2
    End Sub

    ' / --------------------------------------------------------------------------
    Private Sub DataWeb2Grid()
      Dim iStart As Long
      Dim iArr(1) As String
      Dim tmp As String

      '// อ่านชื่อพืชผัก
      iStart = InStr(RichTextBox1.Text, "ชื่อ")
      '// จากตำแหน่งแรก iStart ให้บวกไป 25 หลัก และนับไปอีกทั้งหมด 60 ตัว (เผื่อเอาไว้ กรณีมีชื่อผักยาวๆ)
      tmp = Trim(Mid$(RichTextBox1.Text, iStart + 25, 60))
      '// รูปแบบข้อมูลที่ได้ (ภายใต้เครื่องหมาย Double Quote "")
      ' ">หน่อไม้ฝรั่ง(เขียว)</TD></TR><TR><TD height=10 colSpan="

      '// แยกชุดข้อมูลออกจากกันด้วย </td> แล้วนำเฉพาะ iArr(0) มาเป็นคำตอบ (จะนับถอยหลังเอาก็ได้ แต่จะยุ่งยากกว่า)
      iArr = Split(tmp.ToLower, "</td>")
      '// iArr(0) = ">หน่อไม้ฝรั่ง(เขียว)"
      '// ให้ Replace เครื่องหมาย > ออกไป (เพราะข้อมูลอื่นที่อ่านตัวแรก)
      Dim PlantName As String = Trim(iArr(0).Replace(">", ""))

      '// เริ่มอ่านปี พ.ศ. โดยการค้นหาคำว่า "ราคาเฉลี่ยรายเดือน ประจำปี"
      '// หากเจอให้ iStart + ความยาวของคำมันเอง + 1
      iStart = InStr(RichTextBox1.Text, "ราคาเฉลี่ยรายเดือน ประจำปี") + Len("ราคาเฉลี่ยรายเดือน ประจำปี") + 1
      Dim MyYear As Integer = Mid(RichTextBox1.Text, iStart, 4)

      '// เช็คว่านำข้อมูลเข้าสู่ตารางกริดหรือยัง
      For i = 0 To dgvData.Rows.Count - 1
            '// ตรวจสอบชื่อพืชผักและปี ที่อยู่ในตารางกริด
            If (PlantName = dgvData.Rows(i).Cells(2).Value.ToString) And _
                (MyYear = dgvData.Rows(i).Cells(1).Value.ToString) Then Return
      Next
      '// Loop Data each month.
      Dim MyMonth As String() = New String() {("ม.ค."), ("ก.พ."), ("มี.ค."), ("เม.ย."), ("พ.ค."), ("มิ.ย."), ("ก.ค."), ("ส.ค."), ("ก.ย."), ("ต.ค."), ("พ.ย."), ("ธ.ค.")}
      For i = 0 To 11
            '// ชื่อเดือนแบบย่อ, ปี, ชื่อพืชผัก
            Call ExtractData(MyMonth(i), MyYear, PlantName)
      Next
    End Sub

    ' / --------------------------------------------------------------------------
    Private Sub ExtractData(ByVal MyMonth As String, ByVal MyYear As Integer, ByVal PlantName As String)
      Dim iStart As Long
      Dim iArr(4) As String
      Dim tmp As String
      If RichTextBox1.Text.Length = 0 Then Return
      '// เริ่มต้นอ่านชุดราคาตัวแรกเป็น ราคาเฉลี่ย ... โดยเริ่มนับจากชื่อแรกของเดือน และนับเผื่อไปอีก 195 ตัว
      iStart = InStr(RichTextBox1.Text, MyMonth)
      tmp = Mid(RichTextBox1.Text, iStart, 195)
      '// จะได้--> "ม.ค. </TD><TD class=Tb_cntHP01_02 width=70 align=center>156.45 </TD><TD class=Tb_cntHP01_02 width=70 align=center>240.00 </TD><TD class=Tb_cntHP01_02 width=70 align=center>120.00 </TD><TD"

      tmp = tmp.Replace("<TD class=Tb_cntHP01_02 width=70 align=center>", "")
      '// ให้ตัดคำซ้ำออกไปก็จะเหลือ
      '//--> "ม.ค. </TD>156.45 </TD>240.00 </TD>120.00 </TD><TD"
      '// แยกชุดข้อมูลออกจากกันด้วย </td> ทำให้
      iArr = Split(tmp.ToLower, "</td>")
      '// iArr(0) = ชื่อเดือน
      '// iArr(1) = "156.45 " <-- ราคาเฉลี่ย
      '// iArr(2) = "240.00 " <-- ราคาสูงสุด
      '// iArr(3) = "120.00 " <-- ราคาต่ำสุด
      Dim row As String() = New String() {Trim(iArr(0)), MyYear, PlantName, Trim(iArr(1)), Trim(iArr(2)), Trim(iArr(3))}
      dgvData.Rows.Add(row)
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
      Dim UrlString As String = WebBrowser1.Url.AbsoluteUri.ToString()
      '// จะแสดงลิ้งค์ใหม่ใน Web Address ทันทีที่มีลิ้งค์ไปยังหน้า PriceListItem.aspx
      If InStr(UrlString.ToLower, "PriceListItem.aspx".ToLower) > 0 Then
            txtWebAddress.Text = UrlString
      End If
    End Sub

    ' / --------------------------------------------------------------------------------
    '// การตั้งค่าเริ่มต้นให้กับตารางกริดในแบบ @Run Time
    Private Sub InitializeGrid()
      With dgvData
            .RowHeadersVisible = False
            .AllowUserToAddRows = False
            .AllowUserToDeleteRows = False
            .AllowUserToResizeRows = False
            .MultiSelect = False
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .ReadOnly = True
            .Font = New Font("Tahoma", 9)
            ' จัดความกว้างของแต่ละหลัก
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            .AutoResizeColumns()
            ' Adjust Header Styles
            With .ColumnHeadersDefaultCellStyle
                .BackColor = Color.Navy
                .ForeColor = Color.White
                .Font = New Font("Tahoma", 9, FontStyle.Bold)
            End With
            '// Columns Specified (Count all Columns)
            .ColumnCount = 6
            .Columns(0).Name = "Month"
            .Columns(1).Name = "Year"
            .Columns(2).Name = "PlantName"
            .Columns(3).Name = "Average"
            .Columns(4).Name = "Max"
            .Columns(5).Name = "Min"
            '//
            .Columns("Month").HeaderText = "เดือน"
            .Columns("Year").HeaderText = "ปี พ.ศ."
            .Columns("PlantName").HeaderText = "ผลิตผล"
            .Columns("Average").HeaderText = "ราคาเฉลี่ย"
            .Columns("Max").HeaderText = "ราคาสูงสุด"
            .Columns("Min").HeaderText = "ราคาต่ำสุด"
            '// จัดระเบียบการแสดงผล
            For i = 3 To 5
                .Columns(i).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                .Columns(i).HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight
            Next
      End With
    End Sub

    Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
      Me.Close()
    End Sub

    Private Sub frmHtml2DataGrid_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      Me.Dispose()
      Application.Exit()
    End Sub

End Class
ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่ ...
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] การดึงข้อมูลจากหน้าเว็บเพจ ด้วยการอ่านค่า HTML Tag