Ошибки подключения при получении данных из викиданных? - PullRequest
0 голосов
/ 08 апреля 2019

Я работаю над небольшим проектом, который извлекает данные из Викиданных - у меня есть несколько тысяч запросов, которые работали нормально, но через несколько дней я получаю ошибки ECONNRESET и ETIMEDOUT.

Этоисходный плагин для gatsbyjs, который имеет несколько запросов, которые следуют друг от друга - я не уверен, что это лучший способ сделать это, поэтому любые советы приветствуются.

Способ соединения:

fetch Parliament.uk> Получить Викиданные (pageid)> Получить Викиданные (идентификаторы претензий)> Получить Викиданные (имена претензий)

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()
}
...