[วิธีทำ] สอนเขียน PHP ดึงข่าวจาก LINE TODAY เก็บลงฐานข้อมูล Step by Step[สายเทา]

Guys

Staff Member
Administrator
สมัครเมื่อ
21 พฤษภาคม 2009
คำขอบคุณ
141
#1
คนละเรื่องแล้ว ... มาเข้าเรื่องกันดีกว่า ถ้าใครเป็นสาวก Line ก็คงเห็นบริการ Line Today (https://today.line.me) ที่จะมีข่าวอัพเดท ทุกวัน จากหลาย ๆ สำนัก ซึ่งก่อนหน้านี้จะเปิดเข้าดูได้เฉพาะในมือถือ แต่เดี๋ยวนี้ดีมีอ่านบนเว็บได้ สบายแฮ...

ก่อนหน้าที่จะเปิดให้อ่านบนเว็บได้ ก็แอบคิดในใจ ทำไม ๆ ๆ เนื้อหาดี อัพเดทตลอดแบบนี้ เป็นสิ่งที่เราต้องการนักแล ทำไมไม่มีให้อ่านในเว็บ ... แต่แล้ว Line ก็เข้าข้าง เปิดบริการบนเว็บให้ ฮิฮิ... เสร็จโจร [สายเทานะเออ]

เอาหล่ะ เกริ่นมาเยอะแล้ว สรุป เอาจะมีเขียนโปรแกรม PHP ง่าย ๆ เพื่อดึงเนื้อหาข่าวใน Line Today มาเป็นของเรา แล้วต่อจากนั้นจะเอาไปทำอะไรต่อได้อีกมากมายก่ายกอง แล้วแต่จะคิดได้

บทเรียนนี้จะเขียนไปเรื่อย ๆ อาจจะยาวหรือไม่ ก็ขึ้นกับอารมย์คนเขียน กับฟีดแบ็ค นะครับ เพราะมันสายเทา เนื้อหาจะแบ่งเป็นช่วง ๆ อาจจะต่อเนื่องบ้าง ไม่ต่อเนื่องบ้าง แต่จะเอามาทำเป็นสารบัญให้อีกที

ถึงตอนนี้ ขอเสียงคนสนใจหน่อยครับ ว่ามีสัก 10 คนไหม ใครสนใจรบกวนปูเสื่อ รอไว้หน่อยครับ หนังกลางแปลงกำลังจะฉายแล้ว

ปล. กระทู้นี้เหมาะกับ ผู้สนใจเขียนโปรแกรม PHP + MySQL ระดับเบื้องต้น ถึงกลาง เน้นเขียนง่าย ใช้ได้จริง

credit : http://www.thaiseoboard.com/index.php/topic,386988.0.html

บทที่ 1 เตรียมระบบให้พร้อม

ในการเขียนโปรแกรม PHP + MySQL สิ่งแรกที่จะต้องทำคือต้องมี server ที่มี PHP และ MySQL หรือถ้าใครมี Server ที่เช่าไว้อยู่แล้วก็ง่าย เขียนโค้ดโปรแกรมแล้วก็โยนไปที่ Server ได้เลย ในส่วนนี้รายละเอียดการใช้งานโฮสต่าง ๆ ก็หาอ่านเพิ่มเติมเอานะครับ

ถ้าระบบพร้อมแล้ว ลองเขียนคำสั่ง PHP เพื่อตรวจสอบฟังก์ชั่นสำคัญที่เราจะใช้ในการดึงข้อมูลจากเว็บอื่นมานั่นคือ curl

สร้างไฟล์ bot-01.php จากนั้นให้อัพโหลดขึ้นโฮสที่เตรียมไว้
PHP:
<?php
    $url = "https://today.line.me/th";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT,"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36");
    curl_setopt($ch, CURLOPT_URL, $url);

    $data = curl_exec($ch);
    curl_close($ch);

    echo $data;
?>
คำสั่งด้านบนนี้ จะทำการดึงข้อมูลจาก url คือ https://today.line.me/th
ex.png

โดยมีการกำหนดรายละเอียด
CURLOPT_RETURNTRANSFER = 1 คือให้ส่งค่ากลับเป็น string หรือข้อความ
CURLOPT_SSL_VERIFYPEER = false ไม่ตรวจสอบ SSL Cert // เพื่อใช้งานใน localhost เพิ่มเติมจากท่าน Shaytalay
CURLOPT_USERAGENT = ตัว User Agent ที่จะไปปรากฏที่ Server ของ url เป้าหมาย ตัวนี้สำคัญมาก สำหรับการสับขาหลอก server ควรใช้ user agent ที่มีคนใช้งานเยอะ ๆ หาได้จาก http://www.useragentstring.com...seragentstring.php?name=Chrome
ex.png


จากนั้นเข้า url ที่เราอัพโหลดไฟล์ bot-01.php ขึ้นไป ตัวอย่างเช่น http://class.undergroundclass.com/linetoday/bot-01.php
ex.png

ถ้าระบบเรารองรับ จะเห็นหน้าข้อมูล Line Today ดังภาพ


จบบทที่ 1 ... โปรดติดตาม ตอนต่อไป ...
 
แก้ไขล่าสุดเมื่อ:

Guys

Staff Member
Administrator
สมัครเมื่อ
21 พฤษภาคม 2009
คำขอบคุณ
141
#2
บทที่ 2 เริ่มการตัดตอน

ในบทที่ 1 เราสามารถดึงข้อมูลจาก Line Today มาได้แล้ว ซึ่งจะอยู่ในรูปแบบของภาษา html+javascript แต่ทั้งหมดนั้นมันก็คือข้อความยาว ๆ เท่านั้นเอง
สิ่งต่อไปคือการนำข้อความที่ได้ มาตัดเอาเฉพาะส่วนที่เราต้องการ ซึ้งขันตอนนี้เราจะต้องเขียนคำสั่งในการตัดเอาส่วนที่เราต้องการจากข้อความทั้งหมดที่เรามี โดยจะตั้งชื่อว่า get_string_between() หน้าที่คือตัดเอาเฉพาะส่วนข้อความตรงกลาง จากข้อความหัวและท้ายที่เรากำหนดเข้าไป

PHP:
<?php
/* old function 2016-12-14
function get_string_between($string,$start,$end){
    $arr = explode($end,$string);
    $arr = explode($start,$arr[0]);
    return $arr[1];
}
*/

function get_string_between($string,$start,$end){
    $arr = explode($start,$string);
    $arr = explode($end,$arr[1]);
    return $arr[0];
}
?>
โดย function นี้ จะทำหน้าที่ง่าย ๆ ตัวอย่างเช่น

ข้อความทั้งหมดคือ 0123456789 เราจะตัดเอาเฉพาะ 456 เราจะเอา 3 และ 7 เป็นตัวแบ่ง จะได้คำสั่งประมาณ get_string_between('0123456789','3','7');

โดยการทำงานเป็นขั้นตอนอย่างนี้
$arr = explode($end,$string); // ตัดข้อความโดยใช้ explode โดยเอา ข้อความสุดท้ายที่เราต้องการเป็นตัวแบ่ง แล้วเก็บไว้ในตัวแปร array
โดยข้อความด้านหน้าของตัวแบ่งจะอยู่ใน array ที่ 0 ข้อความที่อยู่หลังจะอยู่ array ที่ 1 (ถ้าตัวแบ่งมีหลายครั้งในข้อความ ก็จะเก็บใน array ตัวถัด ๆ ไป)

จากตัวอย่างขั้นตอนแรกเราจะได้
$arr[0] = 0123456
$arr[1] = 89

ในที่นี่เราสนใจเฉพาะ $arr[0] เพราะเป็นส่วนที่เราต้องการ เพื่อไปตัดต่อในขั้นตอนที่ 2
$arr = explode($start,$arr[0]);
ในลักษณะเดียวกัน เมื่อทำการ explode ก็จะได้
$arr[0] = 012
$arr[1] = 456
ซึ่งใน $arr[1] คือสิ่งที่เราต้องการ จึงส่งค่ากลับออกมาจาก function


โดยการทำงานเป็นขั้นตอนอย่างนี้
$arr = explode($start,$string); // ตัดข้อความโดยใช้ explode โดยเอา ข้อความเริ่มต้นที่เราต้องการเป็นตัวแบ่ง แล้วเก็บไว้ในตัวแปร array
โดยข้อความด้านหน้าของตัวแบ่งจะอยู่ใน array ที่ 0 ข้อความที่อยู่หลังจะอยู่ array ที่ 1 (ถ้าตัวแบ่งมีหลายครั้งในข้อความ ก็จะเก็บใน array ตัวถัด ๆ ไป)

จากตัวอย่างขั้นตอนแรกเราจะได้
$arr[0] = 012
$arr[1] = 456789

ในที่นี่เราสนใจเฉพาะ $arr[1] เพราะเป็นส่วนที่เราต้องการ เพื่อไปตัดต่อในขั้นตอนที่ 2
$arr = explode($end,$arr[1]);
ในลักษณะเดียวกัน เมื่อทำการ explode ก็จะได้
$arr[0] = 456
$arr[1] = 89
ซึ่งใน $arr[0] คือสิ่งที่เราต้องการ จึงส่งค่ากลับออกมาจาก function

เมื่อเราได้ function ในการตัดข้อความที่เราต้องการแล้ว ก็นำมาประกอบร่างกับบทที่ 1 แต่จะจับบทที่ 1 เข้าไปใน function โดยตั้งชื่อว่า get_contents() จะได้โค้ดดังต่อไปนี้

PHP:
<?php
function get_contents($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT,"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36");
    curl_setopt($ch, CURLOPT_URL, $url);

    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

/* old function 2016-12-14
function get_string_between($string,$start,$end){
    $arr = explode($end,$string);
    $arr = explode($start,$arr[0]);
    return $arr[1];
}
*/

function get_string_between($string,$start,$end){
    $arr = explode($start,$string);
    $arr = explode($end,$arr[1]);
    return $arr[0];
}


?>
เมื่อสร้าง function ไว้แล้วก็ทำการเรียกใช้งาน โดย function get_contents() จะทำหน้าที่ดึงข้อมูลจาก url ที่เราต้องการมาให้ จากนั้นใช้ function get_string_between() มาทำการตัดเอาเฉพาะส่วนที่เราต้องการ

*** แต่ get_string_between มีข้อจำกัดอยู่ว่า คำที่จะเป็นจุด start แล้ว end จะต้องเป็นข้อความเดียวที่ปรากฏอยู่ในข้อความต้นฉบับทั้งหมด ห้ามมีซ้ำกันหลายที่ เพราะตัว get_string_between จะไปจับเอาเฉพาะคำแรกที่เจอเท่านั้น หากคำนั้นไปอยู่กลางข้อความที่เราต้องการ มันก็จะตัดเอาเฉพาะส่วนแรก

คราวนี้เราลองมาตัดเอาเฉพาะ discription ของเว็บ Line Today กันดู โดยให้เรา view source หน้า Line today ขึ้นมาดูก่อน จะได้ตามภาพ


ดังนั้นในการกำหนด คำที่จะเอามาตัดส่วนหัวและท้าย ก็ควรเป็น <meta name="description" content=" และ โดย LINE TODAY"> เพราะค้นหาแล้วไม่มีส่วนที่ซ้ำกันอีกในข้อความทั้่งหมด ดังนั้นโค้ดทั้งหมดจะเป็นดังนี้ โดยให้สร้างไฟล์ bot-02.php แล้วใส่โค้ดนี้ลงไป

PHP:
<?php
    function get_contents($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_USERAGENT,"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36");
        curl_setopt($ch, CURLOPT_URL, $url);

        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    function get_string_between($string,$start,$end){
        $arr = explode($start,$string);
        $arr = explode($end,$arr[1]);
        return $arr[0];
    }

    $url = "https://today.line.me/th";
    $contents = get_contents($url);

    $text =  get_string_between($contents,"<meta name=\"description\" content=\"","โดย LINE TODAY\">");

    header("Content-Type: text/html; charset=utf-8");
    echo $text;
?>
จากนั้นลองรันไฟล์ bot-02.php (http://class.undergroundclass.com/linetoday/bot-02.php
ex.png
) จะได้ข้อความตามภาพด้านล่าง


##########################################
2016-12-15 ปรับ function get_string_between()
PHP:
<?php
function get_string_between($string,$start,$end){
    $arr = explode($start,$string);
    $arr = explode($end,$arr[1]);
    return $arr[0];
}
?>
 
แก้ไขล่าสุดเมื่อ:

Guys

Staff Member
Administrator
สมัครเมื่อ
21 พฤษภาคม 2009
คำขอบคุณ
141
#3
บทที่ 3 คัดเอาแต่เนื้อ

ในบทนี้จะเป็นการคัดกรองเอาเฉพาะส่วนที่เป็นสิ่งสำคัญ นั่นก็คือ url ของข่าวแต่ละข่าวในหน้า Line Today เพื่อที่เราจะเก็บข้อมูลข่าวทั้งหมดมาไว้ในกำมือของเราได้
กระบวนการก็ไม่ยุ่งยาก เพียงแต่ต้องสังเกตโค้ดต้นฉบับของ Line Today ว่าส่วนในหรือส่วนที่เราต้องการ โดยทำการ view code ดูจะได้ส่วนที่ต้องการดังภาพ



ส่วนนี้จะเป็นส่วนเนื้อหาของหน้า Line Today ที่เราสามารถตามสืบต่อไปได้ว่า ลิ้งไหนคืออะไร แต่เราจะทำการตัดเอาเฉพาะส่วนนี้มาก่อน โดยใช้ get_string_between()
แต่ใครจะไม่ตัดก็ได้ เพราะขั้นตอนต่อไป จะสำคัญกว่านี้และทำหน้าที่ครั้งเดียวได้เลย แต่เอาเป็นว่าลองใช้ดูหน่อยจะได้คุ้นเคย คำสั่งคือ

PHP:
$text = get_string_between($contents,"<script>var categoryJson =","</script>");
จากนั้นเราจะได้ส่วนของเนื้อหามาเก็บไว้ในตัวแปร $text แล้วก็เข้าสู่กระบวนการสำคัญคือ การคัดกรองเอาเฉพาะลิ้งที่เป็นข่าว ซึ่งมีรูปแบบประมาณนี้

PHP:
https://today.line.me/th/article/df7e6a27d63574ba146fbfc8526f6a197508b56784dbb57577e82d74f4426d82
โดยเราจะใช้ function พระเอกที่มีชื่อว่า preg_match_all() ซึ่งมีหน้าที่ตัดเอาเฉพาะส่วนที่เราต้องการ โดยอาศัยการกำหนดรูปแบบ regular expression ใครไม่รู้จักไปอ่านเพิ่มเอานะครับ โดยการใช้มีรูปแบบคำสั่งดังนี้

PHP:
preg_match_all ("/[URL]https://today.line.me/th/article/(.*)[/URL]"/U", $text, $result);
โดยใช้ $text เป็นข้อความทั้งหมด และ ผลที่ได้จะถูกเก็บใน $result ในรูปแบบ array

ลองมาดูโค้ดเต็มๆ กัน โดยการสร้างไฟล์ bot-03.php แล้วใส่โค้ดดังนี้

PHP:
<?php
    function get_contents($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_USERAGENT,"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36");
        curl_setopt($ch, CURLOPT_URL, $url);

        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    function get_string_between($string,$start,$end){
        $arr = explode($start,$string);
        $arr = explode($end,$arr[1]);
        return $arr[0];
    }

    $url = "https://today.line.me/th";
    $contents = get_contents($url);

    $text = get_string_between($contents,"<script>var categoryJson =","</script>");

    preg_match_all ("/https://today.line.me/th/article/(.*)"/U", $text, $result);

    echo "<pre>";
    print_r($result);
    echo "</pre>";
?>
เสร็จแล้วลองรันดู จะได้ผลลัพท์เป็น array ที่เก็บ url และ hash ของข่าวที่อยู่ใน Line Today นะเวลาปัจจุบันทั้งหมดออกมา
http://class.undergroundclass.com/linetoday/bot-03.php
ex.png




จบบทที่ 3
 
แก้ไขล่าสุดเมื่อ:

Top