如何通过SPARQL获取指定Wikidata实体的全量属性及各类值
问题描述
- 需求:从指定Wikidata实体ID(例如Q39659506)出发,获取对应实体的全部属性列表,最终可直接整理为结构化的Pandas DataFrame,替代请求量大、预处理繁琐的原生API调用、遍历速度慢的第三方Python库方案。
- 待解决问题:现有SPARQL仅能返回值为实体类型的属性,无法获取数值、日期等字面量类型的属性值,也未覆盖数值类值对应的单位信息。
- 原有代码缺陷:强制要求所有属性值必须携带
rdfs:label和schema:description字段,直接过滤掉了无实体页面对应的字面量类型值(数字、日期、普通字符串等)。
可直接使用的SPARQL查询
核心调整点:
- 采用Wikidata官方推荐的属性取值路径,自动取最佳排名的属性值,避免返回已被标记为废弃的重复值
- 用
OPTIONAL关键字包裹实体值专属的标签、描述查询,不会误过滤字面量值 - 单独适配数值类型值的单位提取逻辑,同时返回单位标识和单位名称
- 统一返回结构化字段,查询结果可直接转换为Pandas DataFrame,无需额外复杂预处理
PREFIX wd: <http://www.wikidata.org/entity/> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX p: <http://www.wikidata.org/prop/> PREFIX ps: <http://www.wikidata.org/prop/statement/> PREFIX psv: <http://www.wikidata.org/prop/statement/value/> PREFIX wikibase: <http://wikiba.se/ontology#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX schema: <http://schema.org/> SELECT ?propUrl ?propLabel ?valUrl ?valContent ?valDesc ?unitUrl ?unitLabel WHERE { # 指定目标实体,替换下方Q39659506即可查询其他实体 wd:Q39659506 ?p ?statement . # 仅保留正式业务属性,过滤元数据、反向属性 FILTER(STRSTARTS(STR(?p), STR(p:))) ?property wikibase:claim ?p ; wikibase:statementProperty ?ps ; rdfs:label ?propLabel . # 构造属性直接访问URL BIND(STRAFTER(STR(?property), STR(wd:)) AS ?propId) BIND(IRI(CONCAT(STR(wdt:), ?propId)) AS ?propUrl) # 仅取最佳排名的有效值,排除已废弃的重复值 ?statement ?ps ?valContentRaw ; wikibase:rank wikibase:BestRank . # 处理实体类型值 OPTIONAL { BIND(?valContentRaw AS ?valUrl) ?valUrl rdfs:label ?valEntityLabel . OPTIONAL { ?valUrl schema:description ?valDescRaw . } BIND(?valEntityLabel AS ?valContent) } # 处理字面量类型值(数值、日期、字符串) OPTIONAL { FILTER(!isIRI(?valContentRaw)) BIND(?valContentRaw AS ?valContent) } # 提取数值类型值关联的单位 OPTIONAL { ?statement psv:?ps ?valStruct . ?valStruct wikibase:unit ?unitUrl . FILTER(?unitUrl != wd:Q199) # 过滤无单位的默认标记 ?unitUrl rdfs:label ?unitLabelRaw . FILTER(lang(?unitLabelRaw) = 'en') BIND(?unitLabelRaw AS ?unitLabel) } # 统一限定标签语言为英文 FILTER(lang(?propLabel) = 'en') FILTER(!BOUND(?valEntityLabel) || lang(?valEntityLabel) = 'en') FILTER(!BOUND(?valDescRaw) || lang(?valDescRaw) = 'en') }
返回字段说明
propUrl:属性的唯一标识URLpropLabel:属性的英文名称valUrl:若属性值为Wikidata实体,返回实体URL;字面量类型值该字段为空valContent:统一的属性值内容,实体类型值返回实体英文名称,字面量直接返回数值、日期或字符串内容valDesc:若属性值为Wikidata实体,返回实体的英文描述;其他类型值该字段为空unitUrl:若属性值为带单位的数值类型,返回单位实体URL;其他类型值该字段为空unitLabel:若属性值为带单位的数值类型,返回单位的英文名称;其他类型值该字段为空
使用提示
查询时可直接通过Python的SPARQLWrapper库请求Wikidata SPARQL端点,返回的结果可直接传入pd.DataFrame()构造表格,不需要额外做复杂的字段拆解预处理,查询效率远高于逐属性遍历的API调用、第三方库方案。
内容的提问来源于stack exchange,提问作者Arctic
相关产品推荐
相关产品推荐

