• หน้าแรก
  • หลักสูตร
  • บทความ
  • ร้านค้า
  • ติดต่อเรา
    มีคำถามเกี่ยวกับ odoo ?
    (02) 4302475
    info@odoothaidev.com
    Login
    Odoothaidev - We are Odoo professional in Thailand
    • หน้าแรก
    • หลักสูตร
    • บทความ
    • ร้านค้า
    • ติดต่อเรา

      PhantomJS

      • บ้าน
      • บล็อก
      • PhantomJS
      • PhantomJS คืออะไร ? + สอนวิธีใช้

      PhantomJS คืออะไร ? + สอนวิธีใช้

      • โพสโดย admin
      • หมวดหมู่ PhantomJS, Programming Language
      • วันที่ กรกฎาคม 15, 2019
      • ความคิดเห็น 0 ความคิดเห็น
      • แท็ก PhantomJS

      วันนี้เราจะมาพูดถึง tool ที่กำลังได้รับความนิยมมากอีกตัวหนึ่งนั่นก็คือ PhantomJS โดยปกติแล้ว เวลาเราจะเข้าเว็บเราก็จะต้องเปิด web browser ขึ้นมา แล้วก็ใส่ url ลงไป แต่ PhantomJS นั้นจะแตกต่างจาก web browser อื่นๆ ตรงที่มันจะต้องรันผ่าน command-line เราลองมาดูกันว่าความสามารถของ PhantomJS นั้นจะคุ้มค่ากับการหายไปของ GUI หรือเปล่า ?

      PhantomJS คืออะไร ?

      อย่างที่เกริ่นไปแล้วว่า PhantomJS นั้นเป็น tool ที่ใช้สำหรับเข้าเว็บเหมือนๆ กับ Chrome, Internet Explorer หรือ Firefox เลย แม้ฟังแล้วอาจดูเหมือนไม่มีอะไรน่าสนใจนัก แต่ความพิเศษของมันนั้นอยู่ตรงที่การรันผ่าน command-line ซึ่งมาพร้อมกับ JavaScript API ที่จะทำให้เราสามารถจัดการกับผลลัพธ์ของเว็บนั้นๆ ได้ด้วย

      แล้ว PhantomJS ทำอะไรได้บ้าง ?

      ด้วยความสามารถในการจัดการกับผลลัพธ์ของหน้าเว็บได้ คนจึงนิยมนำ PhantomJS ไปใช้ในงานต่างๆ ดังนี้

      • Testingใช้ควบคู่กับ Test Framework อย่าง QUnit หรือ Jasmine
      • Screen Captureเซฟภาพหน้าเว็บเป็นไฟล์รูปได้ รวมไปถึงกราฟิกอย่าง SVG หรือ Canvas
      • Page Automationทำ DOM Manipulation กับหน้าเว็บหลังจากที่โหลดมาแล้วได้
      • Network Monitoringสามารถตรวจดู network traffic เพื่อนำข้อมูลไปวิเคราะห์ได้

      เมื่อดูจากความสามารถของ PhantomJS เราอาจจะเริ่มคุ้นๆ กับบริการที่มีลักษณะคล้ายๆ แบบนี้มาก่อน ในหัวข้อต่อไป เราจะมาลองใช้ PhantomJS สร้างบริการดังกล่าวขึ้นมาใช้เองดู

      ลองใช้ PhantomJS

      ติดตั้ง PhantomJS

      เพื่อความสะดวกในการใช้งาน ให้เราติดตั้ง PhantomJS จาก npm ของ Node.js ได้เลย (สามารถอ่านพื้นฐานเกี่ยวกับการใช้ Node.js ได้ที่ Node.js คืออะไร ?)

      1
      npm install –g phantomjs

      ลองรัน PhantomJS

      เมื่อได้ติดตั้ง PhantomJS ในรูปแบบ package ของ Node.js แบบ global ไปแล้ว เราก็จะสามารถใช้คำสั่งของ PhantomJS ได้ในทุกๆ ที่เลย โดยรูปแบบของคำสั่งจะเป็นแบบนี้

      1
      phantomjs [options] someScript.js [arg1 [arg2 [...]]]

      ก่อนอื่นให้เราสร้างไฟล์ someScript.js ขึ้นมาก่อน แล้วลองใส่โค้ดง่ายๆ แบบนี้ลงไป

      1
      2
      console.log(‘Siam HTML’);
      phantom.exit();

      จากนั้นก็เอาไฟล์นี้ไปวางไว้ในโฟลเดอร์ myProject ของเรา ตามโครงสร้างนี้

      1
      2
      3
      myProject/
      |
      `— someScript.js               # ไฟล์ script ที่จะเรียกใช้ API ของ PhantomJS

      ทีนี้เราจะลองให้ PhantomJS อ่าน script ที่เราเขียนเอาไว้ในไฟล์ someScript.js ก่อนอื่นก็ให้เราเข้าไปในโฟลเดอร์ myProject ด้วยคำสั่งด้านล่างนี้

      1
      cd myProject

      เมื่อเข้าไปในโฟลเดอร์งานของเราแล้ว ก็ให้ลองรันคำสั่งของ PhantomJS ได้เลย

      1
      phantomjs someScript.js

      หากเราพบข้อความ “Siam HTML” แสดงออกมาที่ command-line ก็แปลว่าเราพร้อมใช้ PhantomJS แล้ว

      Workshop – ลองใช้ PhantomJS

      จากตัวอย่างง่ายๆ ก่อนหน้านี้ทำให้เรารู้แล้วว่า การใช้งาน PhantomJS นั้นก็แค่เขียนโค้ด JavaScript ลงในไฟล์ แล้วก็สั่งให้ PhantomJS รันไฟล์นั้นผ่าน command-line เท่านั้นเอง ทีนี้เรามาลองดูตัวอย่างการใช้ JavaScript API ที่ PhantomJS มีมาให้กันดีกว่า

      1. Page Loading

      อย่างแรกเลยเราลองมาดูความสามารถพื้นฐานของ PhantomJS กันก่อน นั่นก็คือการเปิดหน้าเว็บนั่นเอง โดยเราจะสามารถระบุ URL ของหน้าเว็บที่ต้องการจะเปิดได้ พร้อมกับกำหนด callback function เพื่อที่จะให้ทำอะไรบางอย่าง เมื่อหน้าเว็บนั้นได้ถูกโหลดมาเรียบร้อยแล้ว ลองดูตัวอย่างโค้ดด้านล่างนี้

      1
      2
      3
      4
      5
      6
      var page = require(‘webpage’).create();
      // เปิดหน้าเว็บ http://www.siamhtml.com ขึ้นมา
      page.open(‘http://www.siamhtml.com’, function() {
          // ทำอะไรกับผลลัพธ์ที่ได้ ?
      });

      2. Screen Capture

      สมมติเราอยากจะเซฟหน้าเว็บนั้นๆ ออกมาเป็นไฟล์ภาพ เราก็แค่เพิ่มโค้ดลงไปใน callback function เพียงไม่กี่บรรทัดแบบนี้

      1
      2
      3
      4
      5
      6
      var page = require(‘webpage’).create();
      page.open(‘http://www.siamhtml.com’, function() {
          page.render(‘siamhtml.png’); // เซฟหน้าเว็บเป็นไฟล์ siamhtml.png
          phantom.exit(); // สั่งให้ phantomJS เลิกทำงาน
      });

      หากเราไม่อยากกำหนด URL ลงไปในโค้ดเลย เราก็อาจจะให้มันอ่านจาก argument ที่เราจะส่งเข้าไปตอนรัน PhantomJS ก็ได้ ให้เราแก้โค้ดเป็นแบบนี้

      1
      2
      3
      4
      5
      6
      7
      8
      9
      var page = require(‘webpage’).create(),
          system = require(‘system’),
          url = system.args[1], // url คือ argument ตัวที่ 1
          filename = system.args[2] || ‘screenshot’; // filename คือ argument ตัวที่ 2 แต่ถ้าไม่ใส่มาให้ใช้ค่า screenshot แทน
      page.open(url, function() {
          page.render(filename + ‘.png’);
          phantom.exit();
      });

      ทีนี้เวลาเราจะรัน ก็ให้เรากำหนด URL และชื่อของไฟล์รูปที่ต้องการจะเซฟไปด้วย แบบนี้

      1
      phantomjs someScript.js http://www.siamhtml.com siamhtml

      จากโค้ดด้านบน จะได้ว่า http://www.siamhtml.com และ siamhtml จะเป็น argument ตัวที่ 1 และ 2 ตามลำดับ (url และ filename)

      3. Page Automation

      เราสามารถจัดการกับ DOM ของหน้าเว็บนั้นๆ ได้ โดยจะทำผ่านฟังก์ชัน evaluate() สมมติเราอยากรู้ว่า title ของหน้าเว็บนั้นคืออะไร เราก็จะเขียนแบบนี้

      1
      2
      3
      4
      5
      6
      7
      8
      9
      var page = require(‘webpage’).create();
      page.open(‘http://www.siamhtml.com’, function() {
          var title = page.evaluate(function() {
              return $(‘title’).html(); // ดึงค่า title ออกมาด้วย jQuery
          });
          console.log(‘Page title is ‘ + title);
          phantom.exit();
      });

      จากตัวอย่างด้านบน จะสังเกตว่าเราดึง title มาโดยการใช้ jQuery ซึ่งถ้าหน้าเว็บนั้นๆ มีการใช้ jQuery อยู่แล้วก็จะไม่มีปัญหาอะไร แต่ถ้ายังไม่มี เราก็จะต้องใส่ jQuery ให้มันก่อนโดยใช้ includeJS() แบบนี้

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      var page = require(‘webpage’).create();
      page.open(‘http://www.siamhtml.com’, function() {
          // โหลด jQuery ใส่หน้านั้นๆ
          page.includeJs(“//code.jquery.com/jquery-1.11.0.min.js”, function() {
              var title = page.evaluate(function() {
                  return $(‘title’).html();
              });
              console.log(‘Page title is ‘ + title);
              phantom.exit();
          });
      });

      และจากความสามารถเกี่ยวกับ DOM Manipulation นี้เอง ที่ทำให้เราสามารถใช้ PhantomJS ในการทำ Page Automation ได้ เช่น หลังจากโหลดหน้าเว็บมาแล้ว ก็ให้กรอกข้อความลงในฟอร์ม แล้วสั่งให้ submit ฟอร์มนั้นๆ เป็นต้น หรือจะใช้เพื่อประโยชน์ในการ test ฟังก์ชันต่างๆ ก็ได้

      4. Network Monitoring

      นอกจากนั้น เรายังสามารถดูได้อย่างละเอียดว่าในการโหลดหน้าเว็บนั้นๆ มา มีข้อมูล request และ receive อะไรบ้าง ซึ่งจะมีประโยชน์มากในการใช้วิเคราะห์เรื่อง performance ของหน้าเว็บ ให้เราลองรันโค้ดด้านล่างนี้

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      var page = require(‘webpage’).create();
      page.onResourceRequested = function(request) {
          console.log(‘Request ‘ + JSON.stringify(request, undefined, 4));
      };
      page.onResourceReceived = function(response) {
          console.log(‘Receive ‘ + JSON.stringify(response, undefined, 4));
      };
      page.open(‘http://www.siamhtml.com’);

      เมื่อลองดูผลลัพธ์ที่ได้ เราก็จะเห็นข้อมูลดิบออกมามากมาย ซึ่งเราสามารถนำมาคำนวณเพื่อทำเป็นรายงานได้

      Bonus – ใช้ PhantomJS ทำหน้าเพื่อ SEO ให้กับ SPA

      รู้จักกับ SPA

      อย่างที่เราทราบกันดีว่าการทำเว็บที่มีหน้าเดียวหรือ Single-page Application(SPA) เช่น การใช้ AngularJS นั้น ไม่ค่อยส่งผลดีในแง่ของ SEO เท่าไรนัก เพราะเว็บลักษณะนี้มักจะใช้ JavaScript ในการโหลดเนื้อหาแบบ dynamic ทำให้สิ่งที่ crawler ได้ไปนั้นมีแต่หน้าเปล่าๆ

      HTML Snapshot

      วิธีแก้ก็คือ เราจะต้องสร้างหน้าขึ้นมาอีกหน้าหนึ่ง สำหรับให้ crawler มา index โดยเฉพาะ หรือที่เรียกว่าการทำ HTML Snapshot โดยหน้าที่ว่านี้จะต้องมีเนื้อหาที่ครบถ้วน เพื่อให้ crawler ได้เนื้อหาที่ถูกต้องไป index แต่การจะมาทำ HTML Snapshot ให้ครบทั้งเว็บไซต์นั้นไม่ใช่เรื่องง่ายเลย

      Google ทำอย่างไรกับ AJAX

      ก่อนอื่นเรามาทำความเข้าใจกับการ crawl หน้าเว็บที่เป็น AJAX ของ Google กันก่อน แต่เดิมนั้น crawler ของ Google ไม่สามารถ index เนื้อหาที่ใช้ AJAX ได้ แต่ในปัจจุบัน Google ก็ได้กำหนดวิธีที่จะทำให้เนื้อหาแบบ AJAX สามารถถูก index ได้แล้ว

      วิธีที่ว่านั้นก็คือ เราจะต้องบอก crawler ว่าเว็บเราเป็น AJAX นะ โดยการใส่สิ่งที่เรียกว่า fragment ลงไปใน URL ซึ่ง fragment ที่ว่านั้นก็คือเครื่องหมาย “!” ที่อยู่ตามหลัง “#” นั่นเอง ลองดูตัวอย่างนี้

      1
      http://www.siamhtml.com/ajax.html#!key=value

      เมื่อ crawler เจอ URL แบบนี้ มันจะตีความว่าหน้านี้เป็นหน้า AJAX ที่ทำให้รองรับการ crawl แล้ว แทนที่มันจะไป crawl หน้าปกติ มันก็จะไป request อีก URL แทน ตามรูปแบบด้านล่างนี้

      1
      http://www.siamhtml.com/ajax.html?_escaped_fragment_=key=value

      เราจะเห็นว่า crawler นั้นจะไปแก้ URL ของเรา โดยการแทนที่ fragment ด้วย _escaped_fragment_ ซึ่งสิ่งนี้เองที่ทำให้เราสามารถแยกแยะได้ว่า request ที่เข้ามานั้นมาจาก crawler หรือไม่

      แต่ถ้าเราไม่อยากใส่ fragment เราก็สามารถใช้วิธีใส่ meta tag นี้เอาไว้ที่ head element ก็ได้

      1
      <meta name=“fragment” content=“!” />

      โค้ดด้านบนจะเป็นการบอกว่าหน้าเว็บนี้ มี fragment เป็น “!” ซึ่งก็คือ fragment เปล่าๆ นั่นเอง หาก crawler เจอโค้ดนี้มันก็จะตีความหน้าเว็บนี้เหมือนกับการใส่ fragment ตามปกติไว้ที่ URL เลย

      ใช้ PhantomJS สร้าง HTML Snapshot ให้ Crawler

      เมื่อเราสามารถแยก request ที่มาจาก crawler ออกจาก request ที่มาจากผู้ใช้งานทั่วไปได้ เราก็จะอาศัยมันในการสั่งให้ PhantomJS สร้าง HTML Snapshot ให้กับ URL นั้นๆ ให้เราไปดัก URL ที่ web server เอา หากพบว่ามี _escaped_fragment_ อยู่ใน URL ก็ให้ทำ proxy เข้าเครื่องหรือ port ที่รัน PhantomJS อยู่

      อย่าลืมว่า PhantomJS นั้นจะต้องสามารถแปลง URL ที่มี _escaped_fragment_ กลับเป็น URL เดิมก่อนที่ crawler จะแปลงมาได้ด้วย เพื่อที่จะทำ HTML Snapshot ได้ถูก ในส่วนของการรับ request จาก crawler เราก็อาจใช้ Node.js มาสั่งให้ PhantomJS ทำงาน โดยจะรับ argument เป็น URL ของ request ที่เข้ามาที่ถูกแปลงกลับไปแล้วนั่นเอง

      หลังจากที่ PhantomJS โหลด URL นั้นมาได้แล้ว เราก็อาจเซฟให้เป็นไฟล์ html ไว้ก็ได้ พอมี request เข้ามาอีก ก็ให้ใช้ Node.js เช็คดูก่อนว่ามีไฟล์ html ของ URL นั้นสร้างเอาไว้แล้วหรือยัง ถ้ามีอยู่แล้วก็ให้อ่านไฟล์นั้นแล้ว return กลับไปได้เลย จะได้ไม่ต้องมารัน PhantomJS ให้เสียเวลา หรือเราอาจจะเก็บลงใน memcache แล้วตั้งเวลาหมดอายุแทนการเซฟไฟล์ลง disk ก็ได้ (สำหรับเนื้อหาของการใช้ Node.js ขออนุญาตแยกเป็นอีกบทความ แต่หากใครอยากศึกษาก่อน สามารถอ่านวิธีใช้ Node.js รัน PhantomJS คร่าวๆ ได้ที่เว็บหลัก)

      ตัวอย่างการใช้ PhantomJS เซฟหน้าเว็บเป็นไฟล์ HTML

      สำหรับการเซฟหน้าเว็บเป็นไฟล์นั้นสามารถทำได้ง่ายๆ เลย ลองดูตัวอย่างโค้ดนี้

      1
      2
      3
      4
      5
      6
      7
      8
      var page = require(‘webpage’).create(),
          fs = require(‘fs’);
      page.open(‘http://www.siamhtml.com’, function() {
          // เอาผลลัพธ์ที่ได้เขียนลงในไฟล์ source.html
          fs.write(‘source.html’, page.content, ‘w’);
          phantom.exit();
      });

      แต่อย่าลืมว่าเว็บที่เป็นแบบ AJAX นั้น อาจมีเนื้อหาบางส่วนที่จะโหลดมาทีหลัง วิธีแก้ปัญหาก็คือให้เราใช้ฟังก์ชัน waitFor() เข้ามาช่วย แบบนี้

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      function waitFor(testFx, onReady, timeOutMillis) {
          var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000,
              start = new Date().getTime(),
              condition = false,
              interval = setInterval(function() {
                  if ((new Date().getTime() – start < maxtimeOutMillis) && !condition) {
                      condition = (typeof(testFx) === “string” ? eval(testFx) : testFx());
                  } else {
                      if (!condition) {
                          console.log(“‘waitFor()’ timeout”);
                          phantom.exit(1);
                      } else {
                          console.log(“‘waitFor()’ finished in “ + (new Date().getTime() – start) + “ms.”);
                          typeof(onReady) === “string” ? eval(onReady) : onReady();
                          clearInterval(interval);
                      }
                  }
              }, 250);
      };
      var page = require(‘webpage’).create(),
          fs = require(‘fs’);
      page.open(‘http://www.siamhtml.com’, function() {
          waitFor(function() {
              // รอจนกว่า…
              return page.evaluate(function() {
                  return $(“#ajax_content”).is(“:visible”);
              });
          }, function() {
           // แล้วค่อยทำ…
              fs.write(‘siamhtml.html’, page.content, ‘w’);
              phantom.exit();
          });
      });

      จะเห็นว่าเราสามารถกำหนดเงื่อนไขได้เองว่าจะให้เริ่มทำอะไรตอนไหน จากตัวอย่างด้านบน เราจะสั่งให้เซฟหน้าเว็บเป็นไฟล์ก็ต่อเมื่อ #ajax_content ถูกโหลดมาแล้วนั่นเอง

      บทสรุปการใช้ PhantomJS

      เราคงจะได้เห็นแล้วว่าความสามารถ PhantomJS นั้นน่าสนใจมากแค่ไหน โดยเฉพาะการทำ HTML Snapshot ให้กับ SPA ถึงแม้ว่าสำหรับ Front-end Engineer แล้ว เราอาจจะไม่ค่อยได้ใช้ PhantomJS เท่าไรนัก แต่จริงๆ แล้ว เราอาจจะเคยใช้มันโดยที่ไม่รู้ตัวเลยก็ได้ เพราะ PhantomJS นั้นได้ถูกนำไปใช้ใน tool ต่างๆ ที่ช่วยในการทำเว็บไซต์มากมาย โดยเฉพาะ tool สำหรับ test หน้าเว็บ รวมไปถึง tool อื่นๆ ที่เกี่ยวกับการวิเคราะห์ preformance อีกด้วย

       

      ที่มา : http://www.siamhtml.com/introduction-to-phantomjs/

      แท็ก:PhantomJS

      • Share:
      อวตารของผู้เขียน
      admin

      โพสต์ก่อนหน้า

      Why You Should Read Every Day
      กรกฎาคม 15, 2019

      โพสต์ถัดไป

      Jasper Report: วิธีการตรวจสอบ $P{date} is null ในคิวรี่
      กรกฎาคม 15, 2019

      คุณอาจชอบ

      Automate the Boring Stuff with Python – Ebook
      23 กรกฎาคม, 2019

      https://odoothaidev.com/wp-content/uploa …

      Python Programming for Beginners – Ebook
      23 กรกฎาคม, 2019

      https://odoothaidev.com/wp-content/uploa …

      ทิ้งคำตอบไว้

      อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

      ค้นหาบทความ

      หมวดหมู่

      หมวดหมู่

      • Accounting
      • Adobe XD
      • API
      • Blog
      • Business
      • Buttons
      • CRM
      • Custom Fields
      • Design / Branding
      • Django
      • Ecommerce
      • ERP
      • ERP Flow
      • Express
      • Flectra
      • Form View
      • Frontend
      • Github
      • Github
      • Grant Chart
      • Header
      • iReport
      • Jasper Server & Server
      • Jaspersoft Studio
      • Java
      • JSON-RPC
      • Lazada
      • Linux
      • MLM
      • MRP
      • Nignx Proxy
      • NodeJS
      • Odoo 10
      • Odoo 12 Module
      • Odoo 13
      • Odoo 14 Development
      • Odoo 16
      • Odoo 8
      • Odoo 9
      • Odoo API
      • Odoo Certification
      • Odoo Developer
      • Odoo Ebook
      • Odoo Enterprise
      • Odoo ERP
      • Odoo Event
      • Odoo Implement
      • Odoo Inventory
      • Odoo Report
      • Odoo V15
      • Open Source
      • Open-office
      • OpenERP 7.0
      • PhantomJS
      • Postgres SQL
      • Programming Language
      • Project Management
      • Python
      • Python3
      • Qweb
      • Reporting ระบบรายงาน
      • RML Report
      • Search View and Filters
      • Social Network
      • Statusbar
      • Ubuntu
      • Uncategorized
      • Voip & Call Center
      • Warehouse Management
      • WMS
      • Woocommerce
      • Workflow
      • XML-RPC
      • การ Implement
      • การเก็บข้อมูล Pre-Requirement
      • การเตรียมตัวเพื่อใช้งาน erp
      • ความรู้ด้านการตลาด CRM
      • ธีมเว็บไซต์ Odoo
      • ธุรกิจบริการ
      • ธุรกิจประเภทจัดอบรมสัมมนา
      • ธุรกิจสิ่งพิมพ์
      • นักพัฒนา
      • ประเภทธุรกิจที่เหมาะกับ Odoo
      • ระบบบัญชี
      • ระบบเคลม
      • ลิขสิทธิ์ – License
      Introduction LearnPress – LMS plugin

      Introduction LearnPress – LMS plugin

      Free
      From Zero to Hero with Nodejs

      From Zero to Hero with Nodejs

      Free
      Learn Python – Interactive Python

      Learn Python – Interactive Python

      $69.00

      บทความล่าสุด

      V16 Planned Date of Tasks are invisible.
      12ก.พ.2023
      Odoo Implement Methodology
      29พ.ย.2022
      Odoo Enterprise Subscription Agreement
      29พ.ย.2022
      (02) 430-2475
      info@odoothaidev.com
      Facebook Twitter Google-plus Pinterest

      Odoothaidev by OdooTeaM.

      • Privacy
      • Terms
      • Sitemap
      • Purchase

      เข้าสู่ระบบด้วยบัญชีเว็บไซต์ของคุณ

      ลืมรหัสผ่าน?

      Click to Copy