[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]