(非常)滞后的跟进微格式入门2,介绍了使用微格式2数据的基本知识。最初发布的关于waterpigs.co.uk.
越来越多的人使用微格式2来标记个人网站上的个人资料、帖子、事件和其他数据,使开发人员能够构建以有用和有趣的方式使用这些数据的应用程序。无论您是想为个人网站添加对网络提及评论的基本支持,还是有雄心勃勃的结构化数据软件社会图搜索引擎超级提要阅读器计划,您都需要牢牢掌握如何解析和处理微格式2数据。
选择分析器
要将包含微格式2(或经典微格式,如果支持)标记的数据的网页转换为规范的MF2JSON数据结构,您需要一个解析器。
在撰写本文时微格式2解析器可用于以下编程语言:
存在各种其他语言的解析器,但可能不受积极支持或不支持对解析规范的最新更改。
还有各种网站,您可以使用它们来试验微格式标记,而无需下载库并编写任何代码:
如果您选择的语言目前没有可用的解析器,您有几个选项:
- 从代码中调用现有库之一提供的命令行工具,并使用它们提供的JSON
- 使用一个能够解析网站的在线mf2解析器,并使用它返回的JSON(仅推荐用于非常低的使用量!)
- 编写自己的微格式2解析器!有很多人很乐意帮忙,以及一个与语言无关的测试套件,您可以将实现插入其中进行测试。
获取和分析期间的注意事项
大多数真实的微格式数据都是从URL获取的,URL可能会重定向到不同的URL一次或多次。重定向链中的最终URL称为“有效URL”。HTML通常包含相对URL,为了在上下文之外有用,需要根据基本URL解析相对URL。
如果您的解析器有一个“从URL解析微格式”的功能,那么它应该为您处理所有这些。如果您自己发出请求(例如使用自定义缓存或网络设置),然后将响应HTML和基本URL传递给解析器,请确保使用有效的URL,而不是起始URL!解析器将处理相对URL解析,但它需要知道正确的基本URL。
在解析微格式时,返回非200值的HTTP请求并不一定意味着没有什么可解析的!例如410不见了
响应可能包含一个h条目,其中包含一条消息,解释删除之前存在的任何内容。
存储原始HTML、解析规范JSON和派生数据
在使用微格式2数据时,您通常会从URL获取原始HTML,将其解析为规范JSON,然后最终将其处理为一种更简单、更干净、更干净的格式,以便在您的网站或应用程序中使用。这是同一数据的三种不同表示形式——您很可能最终会将派生数据存储在某个地方以供快速访问,但其他两种情况如何?
经验表明,随着时间的推移:
- 当您添加新功能并处理意外的边缘案例时,特定应用程序清理mf2数据的方式将得到调整和改进
- mf2解析器逐渐得到改进,修复了错误,偶尔还添加了全新的功能。
因此,如果它对您的用例有意义,我建议归档原始HTML的副本以及派生数据,而不归档中间规范JSON。通过这种方式,您可以轻松创建脚本或后台作业来更新基于原始HTML的所有派生数据,同时利用解析器改进和对自己代码的改进,而无需重新提取可能存在数百个断开的链接。
如前一节所述,如果您存档原始HTML以进行重新传递,则需要额外存储有效的URL以获得正确的相对URL解析。
对于某些语言,已经有了库(例如X射线对于PHP),它将为您执行常见的清洁和消毒。如果构建这些库的假设适合您的应用程序,那么您可能可以避免处理原始微格式2数据结构的大量繁重工作!
如果没有,请继续阅读…
一个经过解析的页面可能在不同的位置包含许多微格式数据结构(mf结构)。
看一看您正在阅读的文章的解析规范微格式JSON例如。
项目
是顶级mf结构的列表,每个结构都可以在其下包含嵌套的mf结构属性
或儿童
钥匙。
每个mf结构都保证至少有两个键,类型
和属性
.类型
是识别struct代表什么类型的事物(例如,人、帖子、事件)的主要方法。如果结构一次表示多个事物而不想嵌套它们,那么它们可以有多个类型——例如,详细描述事件的帖子可能同时是h-entry和h-event。结构还可以具有其他顶级键,例如身份证件
和朗
.
一般来说,类型
当处理顶级mf结构以及嵌套在儿童
键。在中找到嵌套的mf结构属性
也会有类型
信息,但它们的用法通常由它们所在的属性名称暗示。
对于许多常见的用例(例如主页提要和配置文件),人们可以通过几种不同的方式嵌套mf结构来实现相同的目标,因此重要的是您的代码能够搜索整个树,而不仅仅是查看顶级mf结构。永远不要假设您要查找的微格式结构将位于项目
列表!你需要搜索整棵树。
我建议编写一些函数,这些函数可以遍历mf树并返回与过滤回调匹配的所有结构。然后,这可以作为为常见任务编写更具体的便利函数的基础,例如在特定类型的页面上查找所有微格式,或者在某个属性与某个值匹配的情况下。
请参见我的microformats2 PHP函数对于一些工作示例。
可能的属性值
mf结构中的每个键属性
dict映射到该属性的值列表。每个属性可以映射到多个值,这些值可以是以下任意值的混合:
一个纯字符串值,不包含HTML,并且不转义HTML实体(例如。<
)
{“项目”: [{“类型”以下为:[“h卡”],“属性”以下为:{“名称”以下为:[“巴纳比·沃尔特斯”]}}]}
(在以后的示例中,我将省略封装{“项目”:[{“类型”:[•••],•••}]}
为了简洁起见,重点是属性
单个mf结构的键。)
嵌入的HTML结构,包含两个键:html格式
,映射到属性的HTML表示,以及价值
,映射到纯文本版本。
“属性”:{“内容”:[{“html”:“<p>内容属于一个帖子,作为原始HTML(或 不).</p> “,”,“value”:“内容属于一个帖子,作为原始HTML(或 不)."}]}
img/alt结构,包含下解析图像的URL价值
,其alt文本位于中高音
.
“属性”以下为:{“照片”: [{“价值”:"https://example.com/profile-photo.jpg",“替代”:“示例人员”}]}
一个嵌套的微格式数据结构价值
包含中包含的数据的明文表示的密钥。
“属性”以下为:{“作者”: [{“类型”以下为:[“h卡”],“属性”以下为:{“名称”以下为:[“巴纳比·沃尔特斯”]},“价值”:“巴纳比·沃尔特斯}]}
所有属性可能有多个值。在您期望单个属性值的情况下(例如。名称
),只需取您找到的第一个值,在需要多个值的情况下,使用您认为有效的所有值。也有一些情况下,使用多个值可能是有意义的,但要根据一些启发式方法确定一个值的优先级,例如,一张h-card可能有多个值网址
值,在这种情况下,第一个通常是“规范”URL,其他URL引用外部配置文件。
让我们依次看看每个潜在的财产价值结构的含义。
首先,永远不要假设属性值是纯文本字符串微格式发布者可以以各种不同的方式嵌套微格式、嵌入式内容和img/alt结构,并且您的消费代码应该尽可能灵活。
为了部分弥补这种复杂性,您可以始终依赖价值
嵌套结构的键,为您提供等效的明文值,无论您找到了什么类型的结构。
当您开始使用微格式2时,编写这样的函数,并养成使用它的习惯每一次您需要属性中的单个明文值:
定义 获取第一个明文(mf_struct,属性名):
尝试:first_val=mf结构['属性'][属性名称][0]如果isinstance(first_val,str):返回第一个值(_V)其他的:返回第一个值(_V)[“值”]除了(IndexError,KeyError):返回 无
其次,永远不要假设特定属性将包含嵌入的HTML结构-这通常适用于内容
,但与应用程序需要嵌入HTML的任何地方都相关。如果要可靠地将值编码为原始HTML,则需要:
- 检查第一个属性值是否是嵌入的HTML结构(即具有
html格式
键)。如果是,则取html格式
钥匙
- 否则,使用上述方法获取第一个明文属性值,然后使用HTML-escape
- 如果两者都未找到,则该属性没有值。
在Python 3.5+中,这可能看起来像这样:
从html格式进口逃跑定义 获取首个html(mf_struct,属性名):
尝试:first_val=mf结构['属性'][属性名称][0]如果isinstance(first_val,dict)和 “html” 在里面第一个(_V):返回第一个值(_V)[“html”]其他的:plaintext_val=获取首个纯文本(mf_struct,属性名)如果明文_val是 不 无:plaintext_val=转义(plainttext_val)返回纯文本_val除了(IndexError,KeyError):返回 无
在某些情况下,您的应用程序可能需要知道一个值是被解析为嵌入式HTML还是纯文本字符串,并以不同的方式存储/处理它们。在所有其他情况下,总是当您需要嵌入HTML数据时,请使用这样的函数。
第三,当期望一个图像URL时,检查img/alt结构,返回到纯文本值(根据具体的用例,假设alt文本为空或推断出合适的文本)。这样的情况可能是一个很好的起点:
定义 获取_ img _ alt(mf_struct,属性名):
尝试:first_val=mf结构['属性'][属性名称][0]如果isinstance(first_val,dict)和 “alt” 在里面第一个值(_V):返回第一个值(_V)其他的:plaintext_val=获取首个纯文本(mf_struct,属性名)如果纯文本_val是 不 无:返回{“值”:纯文本_val,“alt”:''}返回 无
除了(IndexError,KeyError):返回 无
最后,在需要嵌套微格式的情况下,您可能最终会得到其他内容。这是最难处理的情况,也是最依赖于您正在处理的特定数据和用途的情况。例如,如果您希望在作者
属性,但如果使用其他方法,则可以使用以下任何方法:
- 如果您得到的是一个看起来不像URL的普通字符串,请将其视为
名称
没有其他属性的隐含h-card结构的属性(如果需要URL,则可以使用有效URL的主机名,前提是它在上下文中可用作备用值)
- 如果你有一个img-alt结构,你可以处理
价值
作为照片
属性中高音
作为名称
属性,甚至可能使用照片
作为隐含回退的URL网址
属性(尽管这有点推了它一步,在大多数情况下,最好省略网址
)
- 如果你有一个嵌入的HTML结构,那么取它的明文
价值
并使用前两种方法中的一种
- 如果你有一个普通字符串,检查它是否看起来像一个URL。如果是这样,获取该URL并查找一个代表性的h-card作为作者值
- 如果您获得一个带有
网址
属性,但没有照片
,你可以去拿网址
,查找具有代表性的h-card(下一节将对此进行详细介绍),并查看它是否具有照片
财产
- 处理
作者
属性设置为无效,并通过作者算法
前三个是通用原则,可以应用于许多场景,在这些场景中,您期望嵌入mf结构,但却发现了其他东西。然而,最后三个是消费微格式2数据的共同趋势的例子:对于许多常见的使用案例,有一些经过深思熟虑的算法可以用于以标准化的方式解释数据。
了解你的算法和词汇
上述作者算法是用于解决微格式2独立使用中常见问题的几种无需多阶正式建立的算法之一。其他一些值得了解的内容包括:
这些算法的库实现适用于某些语言,尽管它们通常与精确文本略有偏差。看看你能不能找到一个满足你需要的,如果不能,写下你自己的并与社区分享!
除了正式的消费算法外,值得仔细查看您正在使用的微格式词汇表的定义(以及使用真实数据进行测试),并添加对属性或发布技术的支持,您可能第一次没有想到。以下是一些入门示例:
- 如果h-card无效
照片
,看看是否有有效的标志
您可以使用
- 在展示带有特色照片的h-entry时,请同时选中
照片
属性和作为特色的
属性,因为其中一个或另一个可能用于不同的场景
- 在处理地址或位置数据(例如,在h-card、h-entry或h-event上)时,请注意其中之一可能以各种不同的形式出现。共ordinates可能是分离的
纬度
和经度
属性,组合明文地理
属性或嵌入式h-地质
。地址可能是独立的顶级属性或嵌入的h-adr。有许多变体可以完全有效地发布,并且您的消费代码在接受的内容上应该尽可能自由。
- 如果h-entry包含标记为
u形照片
在数位内容
,他们将同时出现在内容
html格式
键,也在照片
属性。如果你的应用程序显示嵌入式内容
HTML而不是使用纯文本版本,并且还支持照片
属性(也可能出现在内容
),您可能需要嗅到内容
,然后从中删除它们或忽略相应的照片
属性以避免将照片显示两次。
整理、验证和截断
在绝大多数情况下,使用微格式2数据涉及处理、存储和重新发布不受信任的潜在危险的输入数据。防止XSS和其他攻击超出了微格式解析算法的范围,因此解析器提供的数据与原始数据源一样危险。您需要采取自己的措施对其进行清理和截断,以便安全地存储和显示。
涵盖所有可能的注入和XSS攻击超出了本文的范围,因此我强烈建议参考OWASP资源XSS预防,Unicode攻击和注入攻击了解更多信息。
除此之外,以下想法是一个良好的开端:
- 尽可能使用纯文本值,仅在绝对必要时使用嵌入式HTML
- 通过备受推崇的HTML消毒剂(如PHP)传递所有内容(HTML或非HTML)HTML净化器。配置它以确保嵌入的HTML不会干扰您自己的标记或CSS。它可能也不应该包含任何javascript。
- 在任何情况下,如果您希望使用特定格式的值,请根据需要对其进行验证。
- 更具体地说,无论你在哪里期望一个URL,都要检查你得到的实际上是一个URL
- 考虑代理资源(如图像),或存储它们的本地副本(必要时减小大小和分辨率),以避免混合内容问题、潜在攻击以及在将来链接中断时丢失图像。
- 为每个单独的外部内容确定相关的最大长度值,并根据需要截断它们。理想情况下,使用语言感知的截断算法来避免将单词拆开。当帖子的内容被截断时,为了方便起见,可以考虑添加“阅读更多”链接。
使用真实世界数据进行测试
网络是一个多样化的地方,微格式是一种灵活、允许的标记结构化数据的方法。通常有几种不同但完全有效的方法可以实现相同的目标,作为mf2数据的良好使用者,您的应用程序应该努力接受尽可能多的方法!
最好的测试方法是真实世界数据。如果您的应用程序在构建时考虑了特定的数据源,那么首先要对其进行测试。如果您想处理更广泛的源代码,最好的方法是确定应用程序使用的词汇表和发布用途,并查看相关的示例部分独立网站用于测试代码的真实网站的wiki页面。
不要忘记根据您在个人网站上发布的示例测试代码!
接下来的步骤
希望本文能帮助您避免许多常见的陷阱,并为您成功地使用真实世界的微格式2数据提供一个良好的开端。
如果你有问题或问题,或者想分享你建立的一些很酷的东西,请加入我们indieweb聊天室.