Node.js เป็น Framework ที่มีความสามารถด้าน Networking และ Internet พร้อมใช้งานทันทีโดยไม่จำเป็นต้องติดตั้ง Package เพิ่มเติม โดยบทความนี้จะสาธิตการเขียนโปรแกรมสำหรับดาวน์โหลดรูปภาพและวีดีโอโดยการใช้ Core Module ของ Node.js ซึ่งเมื่อเข้าใจหลักการเขียนโปรแกรมตามในบทความแล้ว ผู้อ่านก็จะสามารถนำไปต่อยอดในการเขียนโปรแกรม Web Scraping ได้เช่นกันครับ
Path
|-package.json
+-src
| |-index.js
ไฟล์ package.json
{
"scripts": {
"dev": "node src"
}
}
พิมพ์คำสั่งที่ Terminal
# ทดสอบการรันโปรแกรม
npm run dev
ตัวอย่างลิงค์สำหรับดาวน์โหลดรูปภาพ ทั้งภาพนิ่ง ภาพเคลื่อนไหว และวีดีโอสามารถหาได้จากเว็บไซต์ https://imgur.com/ ครับ
ในการส่ง HTTP Request นั้น เราจะใช้ Module ชื่อ https
ซึ่งเป็น Core Module ที่มาพร้อมกับ Node.js อยู่แล้วครับ ซึ่งคำสั่ง https.request()
ถูก Implement ในรูปแบบของ Callback เราจึงไม่สามารถเขียนโค้ดในแบบ async
/await
ได้ครับ
// เรียกใช้ module
const https = require('https')
// ตัวอย่าง permalink จากเว็บ imgur.com ครับ
const url = 'https://i.imgur.com/UDkB5M4.mp4'
// ส่ง request ไปยังเซิร์ฟเวอร์
https.request(url, res => {
// เกิด event ระหว่างรับข้อมูลจากเซิร์ฟเวอร์
res.on('data', chunk => {
// ...
})
// เกิด event เมื่อรับข้อมูลจากเซิร์ฟเวอร์เสร็จสิ้น
res.on('end', () => {
console.log('Finished')
})
// แสดงข้อความ error
res.on('error', err => {
console.log(err.message)
})
}).end()
จากขั้นตอนที่ผ่านมา ข้อมูลที่ส่งมาจากจากเซิฟเวอร์นั้น จะถูกส่งมาเป็น Chunk จำนวนหลายครั้ง ในขั้นตอนนี้จะเป็นการนำ Chunk เหล่านั้นมาต่อเติมเป็น Stream ไปเรื่อยๆ ครับ ซึ่ง Node.js ก็มี Core Module รองรับการจัดการกับ Stream ไว้พร้อมแล้วเช่นกันครับ
ไฟล์ src/index.js
// เรียกใช้ module
const Stream = require('stream').Transform
https.request(url, res => {
// สร้าง instance ของ stream
const stream = new Stream()
res.on('data', chunk => {
// รับข้อมูลจากเซิร์ฟเวอร์และต่อเติม Stream ไปเรื่อยๆ
stream.push(chunk)
})
}).end()
ขั้นตอนสุดท้ายจะเป็นการบันทึก Stream ลงสู่ Disk ซึ่งในขั้นตอนนี้เราจะใช้งาน Core Module ที่ชื่อ fs
ครับ
ไฟล์ src/index.js
// เรียกใช้ module
const fs = require('fs')
https.request(url, res => {
// บันทึก stream เมื่อรับข้อมูลจากเซิร์ฟเวอร์เสร็จสิ้น
res.on('end', () => {
// ใช้ regular expression เพื่อ extract ชื่อไฟล์และนามสกุลจาก url
const pattern = /(\w+\.)+\w+$/
const filename = url.match(pattern)[0]
// เขียน stream ลง disk
fs.writeFileSync(filename, stream)
})
}).end()
ไฟล์ src/index.js
const https = require('https')
const Stream = require('stream').Transform
const fs = require('fs')
const url = 'https://i.imgur.com/UDkB5M4.mp4'
https.request(url, res => {
const stream = new Stream()
res.on('data', chunk => {
stream.push(chunk)
})
res.on('end', () => {
const pattern = /(\w+\.)+\w+$/
const filename = url.match(pattern)[0]
fs.writeFileSync(filename, stream)
})
res.on('error', err => {
console.log(err.message)
})
}).end()