我正在做一个小项目,该项目可以从Wikidata提取数据-我有几千个请求都可以正常工作,但是几天后回来,我遇到了ECONNRESET和ETIMEDOUT错误。
这是gatsbyjs的源插件,具有多个相互接续的查询-我不确定这是否是最好的方法,因此任何建议都会受到赞赏。
其链接方式:
获取parliament.uk>获取wikidata(页面ID)>获取wikidata(声明ID)>获取wikidata(声明名称)
const fetch = require("node-fetch")
const queryString = require("query-string")
exports.sourceNodes = ({ actions, createNodeId, createContentDigest }, configOptions) => {
const { createNode } = actions
// Gatsby adds a configOption that's not needed for this plugin, delete it
delete configOptions.plugins
const processMember = (member) => {
const nodeId = createNodeId(`mp-${
member._about
}`)
const nodeContent = JSON.stringify(member)
const nodeData = Object.assign({}, member, {
id: nodeId,
parent: null,
children: [],
internal: {
type: `memberParliament`,
content: nodeContent,
contentDigest: createContentDigest(member),
},
})
return nodeData
}
const apiOptions = queryString.stringify(configOptions)
const apiUrl = `http://lda.data.parliament.uk/members.json?${apiOptions}`
return (
// Fetch a response from the apiUrl
fetch(apiUrl)
// Parse the response as JSON
.then(response => response.json())
// Process the JSON data into a node
.then(data => {
data.result.items.forEach((member) => {
const nodeData = processMember(member)
// Use Gatsby's createNode helper to create a node from the node data
createNode(nodeData)
})
})
)
}
exports.onCreateNode = ({ actions, node, getNode }) => {
const { createNodeField } = actions
// if (node.internal.type === 'memberParliament') {
// createNodeField({ node, name: 'birthTest', value: 'hello' });
// return
// };
const wikiInfo = async (memberName = 'Jane Doe', wikiProps) => {
const getPageID = async () => {
let wikiApiOptions = queryString.stringify({
action: 'query',
format: 'json',
formatversion: 2,
list: 'search',
srsearch: memberName + ' politician',
redirects: ''
});
let wikiApi = `https://www.wikidata.org/w/api.php?${wikiApiOptions}`;
return fetch(wikiApi)
// Parse the response as JSON
.then(response => response.json())
.then(data => {
if (data.query) {
let memberPageID = data.query.searchinfo.totalhits ? data.query.search[0].title : null;
return memberPageID;
} else {
return null;
}
})
}
const getClaimIDs = async (memberPageID) => {
const results = {};
if (memberPageID) {
for (let key of wikiProps) {
let wikiApiOptions = queryString.stringify({
action: 'wbgetclaims',
format: 'json',
formatversion: 2,
entity: memberPageID,
property: key
});
let wikiApi = `https://www.wikidata.org/w/api.php?${wikiApiOptions}`;
await fetch(wikiApi)
.then(response => response.json())
.then(data => {
switch (key) {
case 'P569':
results[key] = data.claims[key] ? data.claims[key][0].mainsnak.datavalue.value.time : null;
break;
default:
results[key] = data.claims[key] ? data.claims[key][0].mainsnak.datavalue.value.id : null;
break;
}
});
}
return results;
}
}
const getClaimNames = async () => {
for (let result in wikiResults) {
if (wikiResults[result]) {
if (result === 'P569') {
return wikiResults[result];
} else if (result === 'P69') {
let claimID = wikiResults[result];
let wikiApiOptions = queryString.stringify({
action: 'wbgetentities',
format: 'json',
formatversion: 2,
ids: claimID,
languages: 'en',
sites: 'enwiki'
});
let wikiApi = `https://www.wikidata.org/w/api.php?${wikiApiOptions}`;
let claimName = await fetch(wikiApi)
.then(response => response.json())
.then(data => {
return data.entities[claimID].labels.en.value;
});
wikiResults[result] = claimName;
} else {
let claimID = wikiResults[result];
let wikiApiOptions = queryString.stringify({
action: 'wbgetentities',
format: 'json',
formatversion: 2,
ids: claimID,
languages: 'en',
sites: 'enwiki'
});
let wikiApi = `https://www.wikidata.org/w/api.php?${wikiApiOptions}`;
let claimName = await fetch(wikiApi)
.then(response => response.json())
.then(data => {
return data.entities[claimID].labels.en.value;
});
wikiResults[result] = claimName;
}
} else {
wikiResults[result] = null;
}
}
}
const memberPageID = await getPageID();
const wikiResults = await getClaimIDs(memberPageID);
return await getClaimNames().then(() => {
return wikiResults;
});
}
async function addWikiInfo() {
const wikiProps = ['P19','P69','P569'];
if (node.internal.type === 'memberParliament') {
const wikiClaims = await wikiInfo(node.fullName._value, wikiProps).then((data) => {
for (key in data) {
createNodeField({ node, name:[key], value: data[key] });
}
});
};
}
return addWikiInfo()
}