分类
技术

PHP如何解析Youtube的RSS【ChatGPT】

最近我想把我的油管视频的RSS引入到我的其他网站,比如OurCoders里。这本来应该不难。本来OurCoders的代码里面就包含了magpierss,这是一个古老的PHP RSS解析库,但是一直都可以用。

但是今天发现,magpirerss解析不出来,这是因为Youtube的RSS其实跟规范不完全统一,不够合法。之前即使magpirerss可以解析的时候,有些部分的解析也是不完全对的,我还需要写代码来调整解析后的结果。

今天又解析不出来了,于是我干脆想换一个新的RSS解析器吧,毕竟这个都10多年没更新的,有些Bug也没人解决。于是我找到了rss-php。安装rss-php,很容易,它支持composer。安装方法是:

composer require dg/rss-php

使用方法也很简单:

$rss = Feed::loadRss($url);

echo 'Title: ', $rss->title;
echo 'Description: ', $rss->description;
echo 'Link: ', $rss->url;

foreach ($rss->item as $item) {
	echo 'Title: ', $item->title;
	echo 'Link: ', $item->url;
	echo 'Timestamp: ', $item->timestamp;
	echo 'Description ', $item->description;
	echo 'HTML encoded content: ', $item->{'content:encoded'};
}

但是可怕的是换了rss-php还是无法解析。我就想干脆单独自己写解析Youtube RSS的代码吧。

下面是YoutubeRSS的例子:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">
 <link rel="self" href="http://www.youtube.com/feeds/videos.xml?channel_id=UCdhngtoCb1xRmJQqkS5DpfA"/>
 <id>yt:channel:dhngtoCb1xRmJQqkS5DpfA</id>
 <yt:channelId>dhngtoCb1xRmJQqkS5DpfA</yt:channelId>
 <title>Tinyfool的胡说八道</title>
 <link rel="alternate" href="https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA"/>
 <author>
  <name>Tinyfool的胡说八道</name>
  <uri>https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA</uri>
 </author>
 <published>2019-03-26T02:06:01+00:00</published>
 <entry>
  <id>yt:video:0u_rS0CfhFc</id>
  <yt:videoId>0u_rS0CfhFc</yt:videoId>
  <yt:channelId>UCdhngtoCb1xRmJQqkS5DpfA</yt:channelId>
  <title>军事是不是科技大发展的原动力?老范、徐凯和Tinyfool三人谈</title>
  <link rel="alternate" href="https://www.youtube.com/watch?v=0u_rS0CfhFc"/>
  <author>
   <name>Tinyfool的胡说八道</name>
   <uri>https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA</uri>
  </author>
  <published>2024-01-23T00:40:00+00:00</published>
  <updated>2024-01-23T00:40:00+00:00</updated>
  <media:group>
   <media:title>军事是不是科技大发展的原动力?老范、徐凯和Tinyfool三人谈</media:title>
   <media:content url="https://www.youtube.com/v/0u_rS0CfhFc?version=3" type="application/x-shockwave-flash" width="640" height="390"/>
   <media:thumbnail url="https://i1.ytimg.com/vi/0u_rS0CfhFc/hqdefault.jpg" width="480" height="360"/>
   <media:description>成为此频道的会员即可获享以下福利:
https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA/join


本视频字幕使用TinyStudio生成 https://tinystudio.ai/</media:description>
   <media:community>
    <media:starRating count="54" average="5.00" min="1" max="5"/>
    <media:statistics views="2065"/>
   </media:community>
  </media:group>
 </entry>
 <entry>
  <id>yt:video:kj8b3sJ_gJE</id>
  <yt:videoId>kj8b3sJ_gJE</yt:videoId>
  <yt:channelId>UCdhngtoCb1xRmJQqkS5DpfA</yt:channelId>
  <title>老范采访我,问我为啥要做游戏</title>
  <link rel="alternate" href="https://www.youtube.com/watch?v=kj8b3sJ_gJE"/>
  <author>
   <name>Tinyfool的胡说八道</name>
   <uri>https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA</uri>
  </author>
  <published>2024-01-21T01:00:20+00:00</published>
  <updated>2024-01-21T01:00:20+00:00</updated>
  <media:group>
   <media:title>老范采访我,问我为啥要做游戏</media:title>
   <media:content url="https://www.youtube.com/v/kj8b3sJ_gJE?version=3" type="application/x-shockwave-flash" width="640" height="390"/>
   <media:thumbnail url="https://i4.ytimg.com/vi/kj8b3sJ_gJE/hqdefault.jpg" width="480" height="360"/>
   <media:description>成为此频道的会员即可获享以下福利:
https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA/join


本视频字幕使用TinyStudio生成 https://tinystudio.ai/</media:description>
   <media:community>
    <media:starRating count="54" average="5.00" min="1" max="5"/>
    <media:statistics views="2452"/>
   </media:community>
  </media:group>
 </entry>

</feed>

但是写起来好麻烦啊。对啊,我们有 ChatGPT,万事不决问ChatGPT,于是我写下了如下的Prompt:

如下的xml,我希望读取每个entry的id,title,link,published,updated,media:thumbnail,media:description等信息,用PHP如何获得 

ChatGPT回复道:

使用SimpleXML扩展可以轻松地解析这样的XML。但请注意,由于XML具有命名空间,因此需要在处理元素和属性时指定它们。以下是如何用SimpleXML读取每个<entry>的id,title,link,published,updated,media:thumbnail,media:description等信息: 
<?php
$xmlString = '...'; // 这里放你的原始XML字符串
$xml = simplexml_load_string($xmlString);
$xml->registerXPathNamespace('media', 'http://search.yahoo.com/mrss/');
$xml->registerXPathNamespace('yt', 'http://www.youtube.com/xml/schemas/2015');

foreach ($xml->entry as $entry) {
    $id = (string)$entry->id; // 或者使用 $entry->children('yt', true)->videoId
    $title = (string)$entry->title;
    $link = (string)$entry->link->attributes()->href;
    $published = (string)$entry->published;
    $updated = (string)$entry->updated;
    
    // 获取媒体信息
    $mediaGroup = $entry->children('media', true)->group;
    $mediaThumbnail = (string)$mediaGroup->thumbnail->attributes()->url;
    $mediaDescription = (string)$mediaGroup->description;
    
    // 输出信息
    echo "ID: $id\n";
    echo "Title: $title\n";
    echo "Link: $link\n";
    echo "Published on: $published\n";
    echo "Updated on: $updated\n";
    echo "Thumbnail: $mediaThumbnail\n";
    echo "Description: $mediaDescription\n";
    echo "----------------------\n";
}
?>
这段代码首先加载了XML字符串到$xml变量。然后,我们使用registerXPathNamespace()函数来注册XML中使用的命名空间。这对于正确解析media:和yt:前缀的元素至关重要。接着,代码遍历了<entry>标签中的每一个条目,提取和打印了所需的信息。 请注意,由于含有冒号(:)的XML元素属于名称空间,我们需要使用children()方法来访问它们。SimpleXML中的attributes()方法被用于获取元素的属性。 这段代码提供了一个基本的框架,可能需要根据实际XML结构或者特定需求进行适当的调整。同时,确保输入的XML字符串是完整和有效的,这里出于示例缩短了字符串内容。

问题解决了

打赏

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据