power query web api

วิธีใช้ Power Query ดึงข้อมูลจาก Web API : ตอนที่ 3

จากความรู้สองตอนก่อนหน้าที่เราเรียนรู้เรื่อง GET กับ POST ไปแล้ว ในตอนนี้เราจะมาเรียนรู้วิธีการดึงข้องมูลจาก Web API โดยที่ทางเว็บนั้นๆ ไม่ได้มี Document บอกตรงๆ ว่าจะต้องไปดึง API จากไหน ด้วย Syntax อะไรยังไง?

แต่เราก็ยังสามารถรู้ URL ที่จะดึงได้จากการใช้ Inspector ของ Web Browser เช่น Google Chrome ก็มีครับ ซึ่งในบทความนี้ผมจะสอนเองว่าดูยังไง แล้วดึงข้อมูลยังไง ถ้าเจอปัญหาจะแก้ยังไงแบบละเอียดเลย

ตัวอย่าง 1 : ดึงข้อมูลอัตราแลกเปลี่ยนจาก BBL

สมมติว่าจะดึงข้อมูลอัตราแลกเปลี่ยนจากเว็บนี้ https://www.bangkokbank.com/th-TH/Personal/Other-Services/View-Rates/Foreign-Exchange-Rates แม้ว่ามันจะสามารถดึงได้ตรงๆ เลยจากการ Get Data From Web แต่ว่าวิธีนั้นมันไม่มีความยืดหยุ่น เพราะการ Get Data from Web มันจะดึงตาม URL ที่ระบุ ซึ่งจะได้อัตราแลกเปลี่ยนล่าสุดเท่านั้น

ดึงอัตราแลกเปลี่ยนล่าสุด

แต่เพื่อเป็นการฝึกเราจะลองหาเอาอัตราแปลกเปลี่ยนล่าสุดก่อน ซึ่งตอนนี้เรายังไม่รู้ว่าต้องดึง API ไปที่ไหนยังไง ดังนั้นให้เปิด Google Chrome ปกติก่อน แล้วกด F12 เพื่อเปิด Inspector ขึ้นมา แล้วให้กดไปที่ Tab Network แล้วเลือกคำว่า XHR (XMLHttpRequest) จากนั้นให้กดปุ่ม Ctrl+R เพื่อ Record activity ที่เกิดขึ้น ทีนึง

ทีนี้มันจะแสดงว่ามีอะไรส่งกลับมาจาก Server บ้าง ผ่านการ Request แบบไหนยังไง

ถ้าเราคลิ๊กไปแต่ละอันแล้วดู Preview ก็จะเห็นว่ามันส่งอะไรกลับมา ให้ไล่ดูไปจนเจอตัวที่น่าสนใจ เช่น ผมเจออันนี้

ถ้าเราคลิ๊กคำว่า Headers จะเห็นว่าการจะได้ Response แบบนี้เนี่ย มันต้องยิง API ไปที่ไหน และเป็นแบบ GET หรือ POST รายละเอียดยังไง

ถ้าเห็นเป็นแบบ GET ก็ลองเอา URL ไปพิมพ์เล่นก่อน ว่าได้ผลลัพธ์จริงมั๊ย ซึ่งปรากฏว่ามันติดปัญหาเรื่อง subscription key แสดงว่าเว็บนี้อาจมีระบบ Security บางอย่างที่ไม่อยากให้เราดูดข้อมูลไปง่ายๆ ถ้าไม่ได้ดูตรงๆ ผ่านทาง Browser

แสดงว่าการจะยิงไปส่งขอข้อมูลได้นั้น อาจจะต้องมีการระบุข้อมูลใน Header ให้ถูกต้องตามที่เว็บนั้นๆ กำหนดด้วย จึงจะดึงข้อมูลมาได้

ถ้าลองไล่ลงไปดูจะเห็นว่า ใน Request Headers มีข้อมูล subscription key อยู่ด้วย

คราวนี้เราลอง Get Data from Web จาก Power Query แล้วเลือกแบบ Advance เพื่อใส่รายละเอียด Header ลงไป (ผมไม่แน่ใจว่า key นี้มันจะใช้ได้นานแค่ไหนนะครับ แต่แค่โชว์ concept ให้ดูว่า เราสามารถระบุ key ลงในรายละเอียด header ได้นะ)

คราวนี้เราก็จะดึงข้อมูลได้แล้ว ให้กด convert to table แล้ว expand column ได้เลย

ดึงอัตราแลกเปลี่ยนแบบระบุวัน

สมมติผมลองเปลี่ยนวันเป็น 6 พ.ค. ดู จะเห็นว่ามันมี Response กลับมาเพิ่มเติม ถ้าคลิ๊กเข้าไปดูจะเห็น URL ดังนี้

ซึ่งพอเดาได้ว่า

https://www.bangkokbank.com/api/exchangerateservice/Getfxrates/06/05/2021/2/th
https://www.bangkokbank.com/api/exchangerateservice/Getfxrates/วัน/เดือน/ปี/ลำดับเช้าบ่าย/th

ดังนั้นถ้าผมลองเอา Power Query ดึงแลวระบุ key ใน header เหมือนเดิม เราก็จะสามารถมี query ที่ดึงอัตราแลกเปลี่ยนในวันที่เราต้องการได้เลย (จะทำวันที่เป็น text ให้เป็น parameter แล้วใช้ในลักษณะของฟังก์ชันเลยก็ได้)

ตัวอย่าง 2 : ดึงข้อมูล Tag Hit จาก Pantip Hitz

สมมติว่าเราต้องการดึงข้อมูลจากหน้า https://pantip.com/home/hitz ว่ามีอะไรบ้าง หากลอง Get Data from Web จาก Power Query ใน Excel เฉยๆ จะไม่ได้ข้อมูลอะไรขึ้นมาเลย (แต่ถ้าดึงผ่าน Power BI จะได้นะ แต่ก็เห็นไม่ครบทุกองค์ประกอบอยู่ดี) แต่ถ้าทำใน Excel เราต้องดึงผ่าน API เท่านั้น ไม่มีทางเลือกครับ

ก่อนอื่นก็ให้เข้าไปดู XHR เช่นเคย

คราวนี้เราลองดูเรื่อง Tag Hit เพื่อจะดูว่ามีการส่ง Data ว่าอะไรคือ Hashtag ที่ฮิตที่สุดในตอนนี้ (ซึ่ง power bi ก็มองไม่เห็นตัวนี้)

ถ้าเราคลิ๊กคำว่า Headers จะเห็นการ request ของ Tag Hit ที่เราต้องการ

แต่ว่าหากลองเอา URL ดังกล่าวไปพิมพ์ลงใน Browser ก็จะพบว่า มันขึ้น Error ว่า Access Denied แสดงว่าเว็บนี้อาจมีระบบ Security อีกแล้วววว

จากนั้นเราก็ต้องมาหาว่า ต้องระบุรายละเอียดอะไรใน Header ถึงจะเข้าไปดึงข้อมูลได้ ซึ่งบางทีก็ต้องลองผิดลองถูกดูครับ (เพราะ error message ไม่ได้บอกละเอียดเหมือนตัวอย่างก่อนหน้า) แต่ถ้าเดาจากชื่อ header ด็พอเดาได้ว่าอันไหน

จากนั้นเราจะสามารถดึงข้อมูลมาได้แล้ว

ก็ทำการ convert into table / transpose / promote header / แล้ว expand new row / expand column ได้เลย

จะเห็นว่านอกจากจะได้ชื่อ tag แล้ว ยังได้รายละเอียดมาด้วยว่า tag นั้นมีคนดูมากแค่ไหน มีกระทู้เยอะแค่ไหน ซึ่งจะเห็นว่ามีข้อมูลเพิ่มเติมมากกว่าการ get data from web แบบปกติเยอะเลยครับ

ตัวอย่าง 3 : ดึงข้อมูลราคาน้ำมันจาก PTTOR

คราวนี้เราจะดึงข้อมูลราคาน้ำมันจาก https://www1.pttor.com/oilprice-capital.aspx นะครับ ซึ่งถ้า Get data from web เฉยๆ จะไม่เห็นข้อมูลราคาน้ำมันเลย แปลว่าต้องหา API แล้วล่ะ

ซึ่งพอ inspect ดูแล้วจะมี XHR อยู่ตัวเดียวเลย คือ ตัวนี้

พอมาดูที่ Header ปรากฏว่าเป็นแบบ POST ครับ

หากเราลองเอา URL ของ API ไปกรอกเฉยๆ มันจะไม่ได้ผลครับ ดังนั้นเราต้องค้นหาต่อว่าแบบ POST นี้มันส่ง Content อะไรกลับไปให้ Server ซึ่งเลื่อนลงมาจะเห็นดังนี้

คราวนี้เราก็รู้รายละเอียด Body แล้ว ส่วนรายละเอียด Header ก็เหมือนเดิมในตัวอย่าง POST ก่อนหน้า คือ
Content-Type: application/json; charset=UTF-8

ดังนั้นคราวนี้มาสร้าง Query กันล่ะ โดยเราจะ Copy Code มาจาก Query เดิม แล้วดัดแปลงเอา (เพราะกรอกจาก UI ตรงๆ มันไม่ยอม)

//nMonth: "", nYear: "2021", isTH: true
 let
     MyRecord=[nMonth="",nYear="2021",isTH=true],
     Source = Json.Document(Web.Contents("https://www1.pttor.com/oilprice-capital.aspx/SearchOilPrice", 
     [Headers=[#"Content-Type"="application/json; charset=UTF-8"],
     Content=Json.FromValue(MyRecord)
     ]))
 in
     Source

พอกด ok ก็จะได้ผลลัพธ์ดังนี้

ซึ่งพอ Expand จนครบแล้วจะได้แบบนี้เลย

จะเห็นว่ามันมี tag <b> </b> ติดมาด้วย (ซึ่งมันคือตัวหนาในHTML) เราก็จัดการเอาออกซะ
(ง่ายสุดคือ Replace values 2 ที คือเอา <b> ออกทีนึง แล้วค่อยเอา </b> ออกอีกที)

จากนั้อยค่อย Detect Data type ซะ ข้อมูลก็จะกลายเป็นตัวเลขได้อย่างสวยงาม

ทีนี้ถ้าสังเกตตรง MyRecord ที่เราส่งแบบ POST ไปหา Sever นั้น จะเห็นว่ามันระบุเดือน ปี ได้ด้วย ถ้าลองเปลี่ยนเล่น เราก็จะได้ข้อมูลช่วงนั้นตามที่เราต้องการ เช่น ผมแก้เป็นแบบนี้

= [nMonth="5",nYear="2020",isTH=true]

ผลลัพธ์สุดท้ายก็จะได้แบบนี้เลย แปลว่าเราดึงข้อมูลช่วงเวลาได้ตามต้องการอย่างอิสระ (ถ้าใส่เดือนเป็น “” คือเอาทุกเดือน)

แค่นี้เราก็สามารถดึงข้อมูลราคาน้ำมัน ช่วงเดือน ปี ที่ต้องการ ผ่าน API แบบ POST ได้แล้วครับ

ตัวอย่าง 4 : Google ก็มี API มากมายให้ทดลองใช้ได้ฟรี

การดึงข้อมูลผ่าน API นั้นสามารถนำไปประยุกต์ได้หลากหลายมากนะครับ เพราะในโลก internet นั้นมี API เจ๋งๆ มากมาย บริการของ Google ที่เราคุ้นเคยเองก็มีเยอะมาก เช่น Google Maps, Google Translate และอีกมากมาย

อย่างไรก็ตามบริการหลายๆ อันก็ต้องไปสมัคร Account ให้เรียบร้อย ให้มี Key ที่ถูกต้องจึงจะเข้าไปใช้งานได้ ดังนั้นใครอยากลองทำตามตัวอย่างนี้ ก็ต้องสมัคร Cloud API เพื่อเอา Key มาให้ได้ก่อน (ต้องใส่เลขบัตรเครดิตไปก่อน แต่ทดลองใช้ฟรีได้ภายใต้ Credit ฟรีหลายร้อยเหรียญเลย ถ้าใช้จนโควต้าหมด ก็แค่ใช้งานต่อไม่ได้ มันจะยังไม่หักเงินนะ)

พอสมัครแล้ว ให้ไปกด Generate Key ด้วย

และอย่าลืมไป Enable API Service ที่จะใช้ด้วยนะ ไม่งั้น key นั้นจะใช้ไม่ได้

แล้ว search หา API ที่ต้องการเช่น translate เจอแล้วกดเข้าไปแล้ว Enable ซะ

ทีนี้มาดูตัวอย่าง Query ที่เรียกใช้ Google Translate API แบบ POST ซึ่งผมสร้างฟังก์ชันไว้ดังนี้
(เอา key ไปใส่เพิ่มใน query string ใน URL ได้เลย)

แล้วเอาฟังก์ชันที่สร้างไปเรียกใช้กับข้อมูลที่ต้องการจะแปลได้เลย ผลลัพธ์ที่ได้กลับมาจะซ้อนกันหลายชั้นหน่อย ให้ Expand ออกมาให้หหมด จะได้ดังนี้

แปลว่าถ้าเราเข้าถึง API เจ๋งๆ ได้ เราก็ทำอะไรเจ๋งๆ ได้เช่นกัน เช่นใช้ AI Machine Learning ช่วยตีความข้อความว่าเป็นเชิงบวก เชิงลบ, คำนวณระยะทาง ระยะเวลาจากต้นทางไปปลายทางด้วย Google Maps API เป็นต้น


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *