Web Scraping ดึงข้อมูลจากเว็บไซต์ด้วยภาษา PHP

วันที่: 5 พ.ค. 2565 22:06 น.

Web Scraping ดึงข้อมูลจากเว็บไซต์ด้วยภาษา PHP

Web Scraping คือการดูดข้อมูลจากเว็บไซต์ต่าง ๆ ที่เป็นสาธารณะ ไม่ว่าจะเป็นข้อความ รูปภาพ ลิงก์ เบอร์โทรศัพท์ อีเมล และอื่น ๆ ที่เราสนใจ ซึ่งมีประโยชน์อย่างยิ่งในด้านการรวบรวมข้อมูล เช่น ดึงราคาสินค้า เพื่อมาเปรียบเทียบกันในหลาย ๆ เว็บไซต์ หรือดึงกระทู้ล่าสุด โพสล่าสุดเป็นต้น

ในวันนี้ก็ไปเจอเว็บนึง น่าสนใจมากครับ ก็เลยจะพาดึงข้อมูลบทความในเว็บนั้นกัน นั่นคือ samrid.com ครับ และจะใช้ภาษา PHP ในการทำ Web Scraping นะครับ

เริ่มกันเลย

  1. สร้าง folder ชื่ออะไรก็ได้ไว้ใน htdocs ในกรณีนี้ผมจะสร้างชื่อว่า web-scraping นะครับ
  2. เปิด terminal ขึ้นมาแล้วใช้คำสั่ง cd เข้าไปใน folder ที่สร้างไว้
  3. ติดตั้ง Goutte ซึ่งเป็น HTTP client สำหรับ web scraping ผ่าน composer ด้วยคำสั่งนี้
composer require fabpot/goutte
 
สร้างไฟล์ชื่อ get-data.php ในเนื้อหาไฟล์จะมีดังนี้
require_once('vendor/autoload.php');

$url = 'https://samrid.com/category/asp-net-core/';

$client = new \Goutte\Client();
$crawler = $client->request('GET', $url);
$posts = $crawler->filter('.latest-posts article')->each(function ($node) {
    return $post[] = array(
        'title' => $node->filter('article h2.title a')->text(),
        'link' => $node->filter('article h2.title a')->attr('href'),
        'thumbnail' => $node->filter('div.featured-thumbnail img')->attr('src')
    );
});

echo '<pre>';
print_r($posts);
echo '</pre>';

 

อธิบายเพิ่มเติม

ในการ filter เราสามารถทำได้โดย filter จาก css class ของเนื้อหาในเว็บนั้น ๆ เช่น .latest-posts article นั่นคือ class ที่ครอบเนื้อหาที่ต้องการเอาไว้ ซึ่งเมื่อ view source code ดู จะเห็นดังนี้
 

 

จะเห็นได้ว่าข้อมูลใน class ดังกล่าวมี item ที่เป็น article หลายอันเลย และนั่นแหละ คือเป้าหมายของเรา
เราเลยต้องมา loop ออกมา โดยใช้ ->each และ return ออกมาใน function

และแน่นอน เราต้องมาหาส่วนที่เราต้องการใน article อีกที นั่นคือ title link และ thumbnail ซึ่งก็หาจาก class เหมือนเดิมครับ ตามโค้ดด้านบน แล้วก็ print ค่าออกมาดู ถ้าถูกต้องจะได้ตามภาพนี้
 

 

เมื่อได้ข้อมูลมาแล้ว ลองมาจัดให้ดูดีขึ้นด้วย css กัน จะได้โค้ดดังนี้ครับ

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- CSS only -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <title>Document</title>
</head>

<body style="max-width: 900px; background-color: #dff1e8">
    <div class="container py-2">
        <?php
        require_once('vendor/autoload.php');

        $url = 'https://samrid.com/category/asp-net-core/';

        $client = new \Goutte\Client();
        $crawler = $client->request('GET', $url);
        $posts = $crawler->filter('.latest-posts article')->each(function ($node) {
            return $post[] = array(
                'title' => $node->filter('article h2.title a')->text(),
                'link' => $node->filter('article h2.title a')->attr('href'),
                'thumbnail' => $node->filter('div.featured-thumbnail img')->attr('src')
            );
        });

        // echo '<pre>';
        // print_r($posts);
        // echo '</pre>';

        echo '
        <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">';
            foreach ($posts as $p) {
                echo '
            <div class="col">
                <div class="card h-100">
                    <img src="', $p['thumbnail'], '" class="bd-placeholder-img card-img-top" />
                    <div class="card-body">
                        <a class="card-text text-decoration-none stretched-link" href="', $p['link'], '">', $p['title'], '</a>
                    </div>
                </div>
            </div>';
            }
        echo '
        </div>';
        ?>
    </div>
</body>

</html>

 

อ่านเพิ่มเติม

เรื่องอื่น ๆ ที่เกี่ยวข้อง