PHP วิธีดึง Feed และเนื้อหาล่าสุดของเว็บอื่น มาแสดงในเว็บเรา

  • 2 replies
  • 2000 views
ปกติจะใช้คำสั่ง

$feed = curl_init('url feed ของเว็บที่ต้องการ'); // เช่น https://www.klongmuang-krabi.com/feed

แล้วใช้คำสั่ง curl เพื่อดึงเนื้อหาเข้าตัวแปร contents

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$contents = curl_exec($feed);
curl_close($feed);

// ดึงค่าลงมาเก็บในตัวแปร xml ด้วยคำสั่ง SimpleXmlElement
$xml = new SimpleXmlElement($contents );

// จบการดึงค่ามาเก็บ
--------

ปกติถ้าเว็บไหนป้องกัน curl ไว้ เราสามารถใช้คำสั่ง simplexml_load_file ได้เลยโดยไม่ต้องใช้ curl เช่น

$feed = curl_init('url feed ของเว็บที่ต้องการ');
$xml = simplexml_load_file($feed);

// จบการดึงค่ามาเก็บในตัวแปร xml แบบไม่ใช้ curl
-------

ทีนี้เอาค่าต่าง ๆ มากรองแล้วแสดงผล ด้วย loop for เพื่ออ่านค่าทั้งหมดที่มี ใช้ code ดังนี้

----------

for($i=0; $i<count($xml->channel->item); $i++)
   {
   $url = $xml->channel->item[$i]->link;
   $title = $xml->channel->item[$i]->title;
   $description = $xml->channel->item[$i]->description;

   $start1 = strpos($description, '<p>The post');
   $length1 = strlen($description) - $start1;
   $text1 = substr_replace($description, '', $start1, $length1);   

// ตัดคำตั้งแต่ค่าแรกจนถึง </p> และ </div> เพื่อแยกคำ
$cut1 = strrpos($text1,'</div>');
$cut2 = strrpos($text1,'<p>');
$cut3 = strrpos($text1,'</p>');   

// แยกภาพ และเนื้อหา ออกมาเก็บไว้ในตัวแปร            
$image[$i] = substr($text1,5,$cut1); // ปกติตัดตั้งแต่ <div>ภาพ</div>
$text2[$i] = substr($text1,$cut2,$cut3); // ตัดข้อความตั้งแต่ <p>ข้อความ</p>
$the_title[$i]=$title;
$the_url[$i]=$url;   
}

---------
จบคำสั่งแยกข้อมูลที่ต้องการ และเก็บไว้ในตัวแปรแล้ว ทีนี้เราก็เอาค่าที่ได้ไปแสดงตามที่ต้องการได้เลย

เวลาจะแสดงผล ก็ใช้คำสั่งดังนี้

for ($rows=0; $rows<10; $rows++) { // ให้แสดงข้อมูล 10 รายการ ตั้งแต่ 0-9
         echo '<div><a href="'.$the_url[$rows].'" target="_blank">';   
         echo '<h2>'.$the_title[$rows].'</h2>';
         echo '<div>'.$image[$rows].'</div>';
         echo '<p>'.$text2[$rows],3,300,"UTF-8").'</p>';
         echo '</a></div>';
}

// จบการแสดงผล
-------------

ส่วนตัวแปร $cut ต่าง ๆ ถ้าใครเก่งโปรแกรมก็ดัดแปลงแก้ไข code ได้ตามสะดวกจ้า เขียนเอาไว้แบบดิบ ๆ ซึ่งตัวแปรที่ได้ก็จะมี

1. $image[$i] อันนี้เป็นภาพแต่ละหัวข้อ
2. $text2[$i] อันนี้เป็นเนื้อหาตั้งแต่ <p>ไปจนสุด</p>
3. $the_title[$i] อันนี้คือหัวข้อเรื่องแต่ละเรื่อย
4. $the_url[$i] อันนี้คือ url ของเรื่อง

ใครนำไปใช้แล้วดี บอกต่อด้วยนะ

ตัวอย่างการดึงข้อมูล feed จาก https://krabi.vwander.com/feed
มาแสดงในหน้านี้ https://www.klongmuang-krabi.com/the-best-province.html
จำนวน 9 รายการ ในตำแหน่งด้านล่างของ post บน wordpress

ซึ่งสามารถทำได้ ง่ายมาก ๆ ไม่ต้องมี plugin เลย เราสามารถจัดรูปแบบได้ตามต้องการของ theme ที่ใช้



ส่วนเว็บนี้ ในหน้าแรก หัวข้อข่าว ก็ดึง feed มาแสดงด้วยคำสั่งแบบเดียวกัน

แต่ดัดแปลงนิดหน่อย เพื่อน ๆ ลองดูกันได้นะ โดยดึงมาจาก feed ของ มติชนออนไลน์ แสดงแค่ข่าวเดียวทุกชั่วโมง

update code

บางครั้งมันจะขึ้นค่าที่ดึงมาได้เป็นแบบนี้

(function(){window._cf_chl_opt={cvId: '3',cZone: "www.krabi.today",cType: 'managed',cNounce: '45234',cRay: '8b573ac2fa1c26c9',cHash: '6266fedcf4d3fbd',cUPMDTk: "\/feed?__cf_chl_tk=938IUXZb69m1rIMPRtrUTxklriOumlP3gp67sxP4HB8-1724039951-0.0.1.1-4180",cFPWv: 'g',cTTimeMs: '1000',cMTimeMs: '390000',cTplV: 5,cTplB: 'cf',cK: "",fa: "\/feed?__cf_chl_f_tk=938IUXZb69m1rIMPRtrUTxklriOumlP3gp67sxP4HB8-1724039951-0.0.1.1-4180",md:

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

วิธีแก้

<?php
$url = "url ของ feed";

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");
curl_setopt($ch, CURLOPT_REFERER, "https://www.google.com");

$feedContent = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
} else {
    file_put_contents("feed-matichon1.xml", $feedContent);
    echo "บันทึกข้อมูลสำเร็จ";
}

curl_close($ch);
?>

จบ ทำตามนี้ รับรองได้ผลแน่นอน