การดึงข้อมูลจากหน้าเว็บไซต์ โดยใช้ MATLAB
ในบทความนี้ผมจะพูดถึงการดึงข้อมูลที่เราสนใจบนหน้าเว็บไซต์ออกมานะครับ แต่ก็ไม่ใช่ว่าจะทำได้กับทุกเว็บนะครับ วิธีการนี้ทำได้เฉพาะกับเว็บธรรมดา ที่อนุญาติให้เราเข้าถึงข้อมูลได้เท่านั้น
แล้วเราจะรู้ได้ไงละ ว่าเว็บไหนใช้ได้ หรือใช้ไม่ได้
คำตอบคือ เราต้องทดลองใช้คำสั่ง webread เพื่ออ่านข้อมูลจากเว็บนั้นดูครับ ซึ่งเราจะได้ source code ของหน้าเว็บนั้นมา ทีนี้เราก็ไปดูว่าใน source code นั้นมีส่วนของข้อมูลที่เราต้องการอยู่รึเปล่า ถ้ามีก็แสดงว่าเว็บนี้อ่านได้ครับ
ในตัวอย่างนี้ ผมจะแสดงวิธีการอ่านค่าเงินแบบ real time จากเว็บไซต์นี้นะครับ
http://webrates.truefx.com/rates/connect.html?f=html
ซึ่งหน้าเว็บจะเป็นแบบนี้
เราจะเห็นหน้าเว็บแบบโล่งๆ เหมือนรูปข้างบนครับ ไม่มีส่วนตกแต่งเว็บใดๆ ซึ่งเป็นผลดีต่อเรา เพราะส่วนที่เป็น code html ที่เราไม่ต้องการ จะหายไปเยอะเลย ทำให้การค้นหาข้อมูลของเราทำได้ง่ายขึ้น
เมื่อเราอ่าน URL นี้ด้วยคำสั่ง webread เราจะได้ข้อมูลหน้าตาประมาณนี้ครับ
<table><tr><td>EUR/USD</td><td>1547017529625</td><td>1.14</td><td>596</td><td>1.14</td><td>601</td><td>1.14358</td><td>1.14665</td><td>1.14418</td></tr><tr><td>USD/JPY</td>< ....
จริงๆ แล้วข้อมูลที่ได้จะยาวกว่านี้มากครับ แต่ผมยกบางส่วนมาเป็นตัวอย่างให้ดูคร่วๆ เท่านั้น ต่อไปก็คือปัญหาสำคัญของโจทย์นี้ครับ นั่นก็คือ เราจะดึงข้อมูลที่เราต้องการออกมาได้อย่างไร?
คำตอบคือ ไม่มีวิธีการตายตัวครับ เราจะต้องสังเกตุจากข้อมูลที่เรามีเท่านั้น
อย่างเช่นในตัวอย่างนี้ โค้ดที่เราเห็นอยู่ข้างบนนั้นเรียกว่าภาษา HTML ครับ ซึ่งคำสั่ง table ก็คือ คำสั่งการสร้างตาราง หรือพูดง่ายๆ ก็คือ ข้อมูลที่เราเห็นอยู่บนหน้าเว็บนั้น จริงๆ แล้วมันถูกจัดเรียงเอาไว้ในตาราง (แบบไม่เส้นตาราง) ซึ่งถ้าเราลองสังเกตุดู จะเห็นว่ามันจะขึ้นบรรทัดใหม่ทุกครั้งหลังคำสั่ง <tr>
ดังนั้นผมจะใช้คำสั่ง regexp เพื่อแยกข้อมูลหน้าเว็บออกมาเป็นบรรทัดตามที่เราเห็นนะครับ จากนั้นค่อยตรวจสอบข้อมูลแต่ละบรรทัดว่า มีคู่เงินที่เราต้องการดูรึเปล่า ถ้าเจอแล้ว ถ้าเจอแล้ว เราก็ค่อยไปดูอีกครั้งว่าข้อมูลที่เราต้องการอยู่ตำแหน่งไหนในบรรทัดนั้น จากนั้นก็ค่อยดึงข้อมูลนั้นออกมา ขั้นตอนการดึงข้อมูลคร่าวๆ ก็จะมีประมาณนี้ครับ เราลองมาดูตัวอย่างกันเลย
*หมายเหตุ โค้ดตัวอย่างนี้ เป็นการเขียนโปรแกรมแบบฟังก์ชัน ซึ่งเป็นฟังก์ชันที่มี private ฟังก์ชันในตัวเองด้วย ดังนั้นต้องบันทึกไฟล์นี้ในชื่อว่า 'getDatafromWeb.m' เท่านั้นนะครับ
ผลรันที่ได้ก็จะเป็นประมาณนี้ โดยโปรแกรมนี้จะดึงข้อมูลจากเว็บทุก 1 วินาที
สิ่งที่ผมอยากแสดงให้เห็นในบทความนี้ก็คือ ถึงแม้ว่า MATLAB จะมีคำสั่งสำเร็จรูปอยู่มากมาย แต่ก็ไม่ใช่ว่ามันจะมีคำสั่งที่ตรงกับความต้องการของเราแบบเป๊ะๆ ไม่ว่าเราจะเขียนโปรแกรมอะไรก็ตาม มันก็ต้องมีส่วนที่เราต้องวางแผนอัลกอริทึมเอง แล้วค่อยเลือกเครื่องมือมาใช้ตามความเหมาะสม
ซึ่งจะเห็นว่าคำสั่งที่ผมใช้ ก็เป็นคำสั่งทั่วๆ ไปเท่านั้น ไม่ได้มีคำสั่งเฉพาะเจาะจงอะไรเลย ดังนั้นหากใครที่หวังว่าจะใช้ MATLAB โดยหวังพึ่งแค่คำสั่งสำเร็จรูปที่มากับมัน วันนึงคุณจะต้องเจอปัญหาอย่างแน่นอนครับ
แล้วเราจะรู้ได้ไงละ ว่าเว็บไหนใช้ได้ หรือใช้ไม่ได้
คำตอบคือ เราต้องทดลองใช้คำสั่ง webread เพื่ออ่านข้อมูลจากเว็บนั้นดูครับ ซึ่งเราจะได้ source code ของหน้าเว็บนั้นมา ทีนี้เราก็ไปดูว่าใน source code นั้นมีส่วนของข้อมูลที่เราต้องการอยู่รึเปล่า ถ้ามีก็แสดงว่าเว็บนี้อ่านได้ครับ
ในตัวอย่างนี้ ผมจะแสดงวิธีการอ่านค่าเงินแบบ real time จากเว็บไซต์นี้นะครับ
http://webrates.truefx.com/rates/connect.html?f=html
ซึ่งหน้าเว็บจะเป็นแบบนี้
เราจะเห็นหน้าเว็บแบบโล่งๆ เหมือนรูปข้างบนครับ ไม่มีส่วนตกแต่งเว็บใดๆ ซึ่งเป็นผลดีต่อเรา เพราะส่วนที่เป็น code html ที่เราไม่ต้องการ จะหายไปเยอะเลย ทำให้การค้นหาข้อมูลของเราทำได้ง่ายขึ้น
เมื่อเราอ่าน URL นี้ด้วยคำสั่ง webread เราจะได้ข้อมูลหน้าตาประมาณนี้ครับ
<table><tr><td>EUR/USD</td><td>1547017529625</td><td>1.14</td><td>596</td><td>1.14</td><td>601</td><td>1.14358</td><td>1.14665</td><td>1.14418</td></tr><tr><td>USD/JPY</td>< ....
จริงๆ แล้วข้อมูลที่ได้จะยาวกว่านี้มากครับ แต่ผมยกบางส่วนมาเป็นตัวอย่างให้ดูคร่วๆ เท่านั้น ต่อไปก็คือปัญหาสำคัญของโจทย์นี้ครับ นั่นก็คือ เราจะดึงข้อมูลที่เราต้องการออกมาได้อย่างไร?
คำตอบคือ ไม่มีวิธีการตายตัวครับ เราจะต้องสังเกตุจากข้อมูลที่เรามีเท่านั้น
อย่างเช่นในตัวอย่างนี้ โค้ดที่เราเห็นอยู่ข้างบนนั้นเรียกว่าภาษา HTML ครับ ซึ่งคำสั่ง table ก็คือ คำสั่งการสร้างตาราง หรือพูดง่ายๆ ก็คือ ข้อมูลที่เราเห็นอยู่บนหน้าเว็บนั้น จริงๆ แล้วมันถูกจัดเรียงเอาไว้ในตาราง (แบบไม่เส้นตาราง) ซึ่งถ้าเราลองสังเกตุดู จะเห็นว่ามันจะขึ้นบรรทัดใหม่ทุกครั้งหลังคำสั่ง <tr>
ดังนั้นผมจะใช้คำสั่ง regexp เพื่อแยกข้อมูลหน้าเว็บออกมาเป็นบรรทัดตามที่เราเห็นนะครับ จากนั้นค่อยตรวจสอบข้อมูลแต่ละบรรทัดว่า มีคู่เงินที่เราต้องการดูรึเปล่า ถ้าเจอแล้ว ถ้าเจอแล้ว เราก็ค่อยไปดูอีกครั้งว่าข้อมูลที่เราต้องการอยู่ตำแหน่งไหนในบรรทัดนั้น จากนั้นก็ค่อยดึงข้อมูลนั้นออกมา ขั้นตอนการดึงข้อมูลคร่าวๆ ก็จะมีประมาณนี้ครับ เราลองมาดูตัวอย่างกันเลย
*หมายเหตุ โค้ดตัวอย่างนี้ เป็นการเขียนโปรแกรมแบบฟังก์ชัน ซึ่งเป็นฟังก์ชันที่มี private ฟังก์ชันในตัวเองด้วย ดังนั้นต้องบันทึกไฟล์นี้ในชื่อว่า 'getDatafromWeb.m' เท่านั้นนะครับ
%% Main function function getDatafromWeb %TF Day: time , Bid , Ask , Low , High , Open URL = 'http://webrates.truefx.com/rates/connect.html?f=html'; symbol = 'GBP/USD'; %show real time data Bid = getData(symbol,URL); figure('tag','Symbol','menubar','none'); RTm = Bid.*ones(60,1); x = [1:60]'; AX = plot(x,RTm,'b'); s = sprintf('%s (%7.5f)',symbol,Bid); title(s); while(true) f = findobj('tag','Symbol'); if(isempty(f)) break; end RTm = circshift(RTm,-1); Bid = getData(symbol,URL); RTm(end) = Bid; set(AX,'Ydata',RTm); s = sprintf('%s (%7.5f)',symbol,Bid); title(s); pause(1); end close all; end %% Private function function Bid = getData(symbol,URL) page = webread(URL); symbol = upper(symbol); dt = regexp(page,'<tr>','split'); L = length(dt); for m=1:L A = dt{m}; B = strfind(A,symbol); if(not(isempty(B))) C = regexp(A,'<td>','split'); D = C{4}; E = C{5}; Bid = [D(1:end-5) E(1:end-5)]; Bid = str2double(Bid); break; end end end
ผลรันที่ได้ก็จะเป็นประมาณนี้ โดยโปรแกรมนี้จะดึงข้อมูลจากเว็บทุก 1 วินาที
สิ่งที่ผมอยากแสดงให้เห็นในบทความนี้ก็คือ ถึงแม้ว่า MATLAB จะมีคำสั่งสำเร็จรูปอยู่มากมาย แต่ก็ไม่ใช่ว่ามันจะมีคำสั่งที่ตรงกับความต้องการของเราแบบเป๊ะๆ ไม่ว่าเราจะเขียนโปรแกรมอะไรก็ตาม มันก็ต้องมีส่วนที่เราต้องวางแผนอัลกอริทึมเอง แล้วค่อยเลือกเครื่องมือมาใช้ตามความเหมาะสม
ซึ่งจะเห็นว่าคำสั่งที่ผมใช้ ก็เป็นคำสั่งทั่วๆ ไปเท่านั้น ไม่ได้มีคำสั่งเฉพาะเจาะจงอะไรเลย ดังนั้นหากใครที่หวังว่าจะใช้ MATLAB โดยหวังพึ่งแค่คำสั่งสำเร็จรูปที่มากับมัน วันนึงคุณจะต้องเจอปัญหาอย่างแน่นอนครับ