SPARQLWrapper返回XML而非CSV,如何将宝可梦数据导入SQL表?
解决Wikidata SPARQL结果转SQL表的问题
问题1:CSV格式返回异常的修复
你遇到的ValueError是因为SPARQLWrapper的convert()方法处理CSV返回时,没有正确解析成可被pandas读取的文本流。直接获取响应的原始字节内容,用BytesIO包装后即可正常读取:
from SPARQLWrapper import SPARQLWrapper import pandas as pd from io import BytesIO sparql = SPARQLWrapper("https://query.wikidata.org/sparql") sparql.setQuery(""" PREFIX wd: <http://www.wikidata.org/entity/> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX wikibase: <http://wikiba.se/ontology#> SELECT DISTINCT ?pokemon ?pokemonLabel WHERE { ?pokemon wdt:P361 wd:Q3245450. SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". } }""") # 设置返回格式并指定正确的请求头 sparql.setReturnFormat('csv') sparql.addCustomHttpHeader('Accept', 'text/csv') # 获取原始响应字节,包装成pandas可读取的流 result = sparql.query().response.read() df = pd.read_csv(BytesIO(result)) # 导入SQL表 df.to_sql('PokemonDBP', conn, if_exists='replace', index=False)
问题2:JSON输出顺序错误的修复
你之前的循环把字段顺序写反了,而且?pokemon返回的是完整URI,想要提取Q编号可以通过字符串截取。整理数据后转成DataFrame即可导入SQL:
from SPARQLWrapper import SPARQLWrapper, JSON import pandas as pd sparql = SPARQLWrapper("https://query.wikidata.org/sparql") sparql.setQuery(""" PREFIX wd: <http://www.wikidata.org/entity/> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX wikibase: <http://wikiba.se/ontology#> SELECT DISTINCT ?pokemon ?pokemonLabel WHERE { ?pokemon wdt:P361 wd:Q3245450. SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". } }""") sparql.setReturnFormat(JSON) result = sparql.query().convert() # 整理数据:提取Q编号和宝可梦名称 data = [] for res in result["results"]["bindings"]: pokemon_id = res["pokemon"]["value"].split('/')[-1] # 从URI截取Qxxxx部分 pokemon_name = res["pokemonLabel"]["value"] data.append({"pokemon": pokemon_id, "pokemonLabel": pokemon_name}) # 转成DataFrame后导入SQL df = pd.DataFrame(data) df.to_sql('PokemonDBP', conn, if_exists='replace', index=False)
额外说明
- 两种方法都能实现需求:CSV方式更直接,JSON方式可灵活处理字段格式(比如提取Q编号)。
- 确保
conn是已正确建立的SQLAlchemy连接或数据库连接对象。
内容的提问来源于stack exchange,提问作者user24881603
相关产品推荐
相关产品推荐

