为什么Facebook和Twitter在解析RDFa元数据方面如此糟糕?

Facebook和Twitter都选择使用RDFa来实现“优化链接共享”元数据格式。好吧,似乎Twitter直到后来才意识到这一点。无论如何,为什么这两个拥有大量工程资源的社交媒体平台在解析来自网页的RDFa数据时表现得如此糟糕?

本文的要点是重点介绍Facebook是如何选择RDFa的——而Twitter却倒退了回去,但甚至没有实现一个最小的RDFa解析器来从网站检索元数据。

这意味着,例如,一个元标记存储内容适用于多个词汇表(Twitter card和Open Graph)的属性必须不必要地重复,甚至元元素本身也是冗余的。但我说得太快了,让我回到正题上。

RDFa的“超淡味”

推特卡’是Twitter的名字,这是为了在共享链接中启用富片段的微型元数据格式。这些片段可以包括平台用户之间共享的缩略图和链接标题等细节。Twitter卡片依赖于标记,乍一看似乎是RDFa,但却是明显的结果船货崇拜复制类似于元数据格式的东西,却没有真正理解它们在web上的用途和上下文。

Facebook的“开放图谱协议“(OGP)在技术上更有能力,即使只是在理论上,因为它基于RDFa的“超轻型”变体。从现有的文档来看,RDFa和OGP使用的任何东西之间的主要区别是,后者只能设置内的元件元素。这不是来自RDFa的限制,也不是OGP目的所必需的,但它是Facebook的工程师们随意设定的限制。

谈到RDF属性(RDFa),您至少应该有点熟悉RDFa核心语法为了跟yabo亚博体育下载随本文的学习。这里是一个快速复习:RDF属性允许在HTML标记中嵌入语义上有意义的内容。类的嵌入的元数据键值对是与本文相关的语法所限制的财产(关键)和属性内容属性(值):

@content:一个字符串,用于提供机器可读的内容[…]

@属性:用空格分隔的[术语]列表。"

注意,这里没有提到的名字属性在RDFa中没有任何意义。在本文的示例中使用它的目的是为了非rdfa元数据使用者和遗留系统(并说明这一点)。我将在下一节中回到这一点。

为了简便起见,请想象一下,本文中所有的例子都已经宣布了下述的命名空间。yabo亚博体育下载无论是微博还是Facebook的关心命名空间和仅支持自己的硬编码命名空间前缀。这是另一次的讨论,但是。

Twitter没有为Twitter卡片词汇表提供名称空间URL。然而,他们确实有一个如上示例所示的约定。

我做了一些实验,看看Twitter和Faceboook的机器人是如何以Twitter卡和Open Graph协议格式处理元数据的。接下来的两个部分将讨论如何使用这些格式提取页面标题。

让我们观察Twitterbot解析

尽管推特不正确建议中指定键值的名字属性,我将完全忽略它而使用它财产属性中的例子。

财产属性是正确的选择,根据RDFa标准,它也是通过Twitterbot支持。决定使用的名字可能是基于一个糟糕的设计决策,我怀疑其根源在于工程师在设计他们的RDFa模仿格式时不熟悉RDFa。

让我们看看一些不可行但完全有效的例子:

< meta内容= "大标题" name="title" property="twitter:title"> 大标题“属性=”dc:标题twitter:标题“> 大标题“数据潜水艇=“海洋”属性= "推特:“>

然后请将上述例子与这些工作例子进行比较:

< meta内容= "大标题“property=”twitter:title“name=”title“> 大标题" >

这五个例子都是完全正确的应该奏效的。然而,Twitter只能从最后两个示例中读取元数据。令人担忧的是,重要性似乎是按元素属性的顺序排列的。的内容财产属性也被视为一个精确匹配密钥,而不是令牌的列表。

这里只有两个结论可以从在工作和非工作示例的不同可以得出:

  1. Twitter的工程师在设计Twitter卡片时对HTML和RDFa一无所知。
  2. Twitterbot在解析HTML时犯了最大的错误!他们regex汤匹配标签和属性而不是解析标记!他们做得也很糟糕。

震惊的猫头鹰发现Twitter不能解析HTML

除了震惊和恐惧,这对网络意味着什么?更多的多余的标记。在理想的情况下,每个元数据消费者都会同意元数据描述符的公共核心。没有一个元数据标准,每个元数据使用者至少应该被期望以一种合理的方式解析RDFa数据。下面的例yabo亚博体育下载子应该涵盖了所有的基础:

让我们观察Facebot解析

但是等等,Facebook呢?他们的Open Graph协议实现似乎是围绕着对RDFa语法的理解而设计的,而不仅仅是像我们在Twitter卡中看到的那样的货物选择(模仿)语法。Facebook的facebookexternalhit机器人,被亲切地称为Facebot,似乎比Twitterbot更有能力,它的错误信息表明它正在解析标记。然而,实现仍然有很多需要改进的地方。

让我们来看看一些无效但完全有效的例子:

< meta内容= "大标题“属性=” dc.title OG:标题 “> <元含量=”大标题"属性=" og:标题"> 大标题“name = "标题"属性= " og:标题“>

然后请将上述例子与这些工作例子进行比较:

< meta内容= "大标题"属性="og:标题"> 大标题”属性= " og:标题标题“name = >

Facebot,就像Twitterbot一样,似乎没有得到关于这个问题的备忘录财产属性是用空格分隔的术语列表。Facebot只会做精确的匹配属性= " og:标题",甚至不处理任何空格剥离。Twitterbot至少可以处理空格剥离,即使它不知道它可以是一个空格分隔的列表。

像Twitterbot, Facebot处理的名字属性为重要的,即使它在RDFa解析中没有意义。如果这两个机器人出现在a之前,它们只有任何未预料到的属性有问题财产在元素。同样,我想提醒读者,属性的顺序持有或者RDFa的,也不HTML没有意义。

你不知道吗……facebookexternalhit机器人也regex汤匹配标签和属性而不是像任何元数据消费者那样解析数据!

对从网页中提取元数据的状态感到震惊。

够了愚蠢的猫头鹰!

这个问题应该如何解决呢?

这个问题的答案几乎总是在解析XML表示(如DOM或XDM)上使用XPath。使用XPath解析原始HTML文档不太可能成功,因为作者是用HTML编写的,而XPath只对格式良好的XML文档进行操作。

幸运的是,有一些标准化的过程可以将HTML处理成解析后的XML表示,如DOM或XDM。现在在web浏览器中显示的这个文档就是这个过程的一个例子。有很多库可供开发人员选择,可以从HTML文档创建这种表示。

下面的Xyabo亚博体育下载Path将从文档中读取Open Graph协议标题元数据,并尊重OGP标准的当前限制:

元(包含(concat(' ',正常化空间(@property), ' '), ' og:title ')]/@content

或者,如果您想要完全的RDFa支持,那么这将允许您解析来自内容属性,如果没有,则回退到元素文本节点内容属性。该属性可以从任何元素标题元素似乎合适,或者可能是ah1元素在页面上某处进一步下降),而不仅仅是meta元素。

(*[包含(concat(“normalize - space (@ property), ' '),“噩:标题”)]/ @content | *(包含(concat(“,normalize - space (@ property), ' '),“噩:标题”)]/ @文本()) (位置() = 1]

上面的XPath将返回字符串"大标题“根据RDFa标准,以下所有例子:yabo亚博体育下载

<标题内容= "大标题”属性= " og:标题”>好的标题
 大标题= " " > < meta内容大标题“名称=” 标题”属性= “DC:标题OG:标题”> 大标题< / h1 >

下面的Dyabo亚博体育下载OMquerySelector管理相同的壮举:

文档。querySelector('meta[property~= ' og:title '], *[property~= ' og:title ']');

总之

-那么XPath是Twitterbot和Facebot的正确工具吗?嗯,是的。可能。他们为什么不用呢?他们一点也不在乎。发布者将调整他们的标记以与实际使用的弱实现协同工作。

来回答这个标题的首要问题:Facebook和Twitter不擅长以自己的标准格式从网站提取元数据,原因是它们没有解析数据而是使用基于一厢情愿的元数据提取技术。如果他们的解决方案在StackOverflow编码论坛上被建议作为这个问题的答案,它将会被投下反对票而被遗忘。

既然您已经阅读了本文,并且对这篇文章有了更好的了解,那么您就没有理由不在项目中实现适当的文档解析。不要重复Facebook和Twitter的错误。