Javascript 当请求返回错误时,如何从网站中刮取数据

Javascript 当请求返回错误时,如何从网站中刮取数据,javascript,node.js,web-scraping,Javascript,Node.js,Web Scraping,在过去的几天里,我一直在尝试从https://www.fibank.bg/en/currency-rates使用JavaScript和Node.js。不幸的是,目前似乎没有任何效果。第一次尝试是使用cors anywhere包,该包到目前为止一直有效。但是,请求返回一个关于浏览器插件的错误。第二次尝试是在本教程https://hackernoon.com/a-guide-to-web-scraping-with-javascript-and-nodejs-i21l3te1但是CORS也有问题。令

在过去的几天里,我一直在尝试从
https://www.fibank.bg/en/currency-rates
使用JavaScript和Node.js。不幸的是,目前似乎没有任何效果。第一次尝试是使用cors anywhere包,该包到目前为止一直有效。但是,请求返回一个关于浏览器插件的错误。第二次尝试是在本教程
https://hackernoon.com/a-guide-to-web-scraping-with-javascript-and-nodejs-i21l3te1
但是CORS也有问题。令我惊讶的是,当我尝试使用删除了用户代理的postman获取请求时,请求返回页面。但是,如果我在node.js的标题中手动设置用户代理,我会得到与以前相同的错误。我猜有一些服务器端限制,cors anywhere可能会触发它,但我不知道为什么postman请求有效,而node.js无效,以及如何解决这个问题

import React, { useEffect, useState } from "react";
const getCurrencyStr = (el) =>
  (el.childNodes[0].nextElementSibling.innerHTML || "").trim();
const CURRENCIES = ["EUR", "USD", "GBP"];
const DEFAULT_CURRENCY = {
  USD: {
    buy: 1.0,
    sell: 1.0,
  },
  EUR: {
    buy: 1.0,
    sell: 1.0,
  },
  GBP: {
    buy: 1.0,
    sell: 1.0,
  },
};
const FIBankRate = () => {
  const [CurrencyRates, setCurrencyRates] = useState({
    USD: {
      buy: 1.5812,
      sell: 1.6461,
    },
    EUR: {
      buy: 1.94,
      sell: 1.96,
    },
    GBP: {
      buy: 2.078,
      sell: 2.186,
    },
  });
  useEffect(() => {
    fetch(`https://www.fibank.bg/en/currency-rates`, {
      headers: {
        "Content-Type": "application/json",
        "User-Agent": "Mozilla/5.0",
      },
    })
      .then((response) => response.text())
      .then((result) => {
        if (result) {
          console.log(result);
          const el = document.createElement("html");
          el.innerHTML = result;
          const arr = Array.from(el.getElementsByTagName("tr"));
          console.log(arr);
          const filtered = arr.filter((el) => {
            return CURRENCIES.includes(getCurrencyStr(el));
          });
          filtered.forEach((el) => {
            const currentCurrency = getCurrencyStr(el);
            if (currentCurrency && currentCurrency in DEFAULT_CURRENCY) {
              DEFAULT_CURRENCY[currentCurrency].buy =
                el.childNodes[5].childNodes[1].childNodes[3].innerHTML;
              DEFAULT_CURRENCY[currentCurrency].sell =
                el.childNodes[5].childNodes[3].childNodes[3].innerHTML;
            }
          });
          setCurrencyRates(DEFAULT_CURRENCY);
        } else {
          throw new Error(result.message);
        }
      })
      .catch((error) => console.log(error.message));
  }, []);

  return (
    <tr>
      <td>FIBank</td>
      <td>{CurrencyRates.USD.buy}</td>
      <td>{CurrencyRates.USD.sell}</td>
      <td>{CurrencyRates.EUR.buy}</td>
      <td>{CurrencyRates.EUR.sell}</td>
      <td>{CurrencyRates.GBP.buy}</td>
      <td>{CurrencyRates.GBP.sell}</td>
    </tr>
  );
};
export default FIBankRate;

import React,{useffect,useState}来自“React”;
常量getCurrencyStr=(el)=>
(el.childNodes[0].nextElementSibling.innerHTML | | |“”).trim();
常量货币=[“欧元”、“美元”、“英镑”];
常量默认值\u货币={
美元:{
购买:1.0,
销售:1.0,
},
欧元:{
购买:1.0,
销售:1.0,
},
英镑:{
购买:1.0,
销售:1.0,
},
};
常数FIBankRate=()=>{
const[CurrencyRates,setCurrencyRates]=useState({
美元:{
买入价:1.5812,
卖出价:1.6461,
},
欧元:{
买入价:1.94,
卖出价:1.96,
},
英镑:{
买入价:2.078,
销售:2.186,
},
});
useffect(()=>{
取回(`https://www.fibank.bg/en/currency-rates`, {
标题:{
“内容类型”:“应用程序/json”,
“用户代理”:“Mozilla/5.0”,
},
})
.然后((response)=>response.text())
。然后((结果)=>{
如果(结果){
控制台日志(结果);
const el=document.createElement(“html”);
el.innerHTML=结果;
const arr=Array.from(el.getElementsByTagName(“tr”);
控制台日志(arr);
常数筛选=阵列筛选((el)=>{
返回货币。包括(getCurrencyStr(el));
});
已过滤。forEach((el)=>{
const currentCurrency=getCurrencyStr(el);
if(当前货币和当前货币默认值){
默认货币[currentCurrency]。购买=
el.childNodes[5].childNodes[1].childNodes[3].innerHTML;
默认货币[currentCurrency]。卖出=
el.childNodes[5].childNodes[3].childNodes[3].innerHTML;
}
});
设置货币汇率(默认货币);
}否则{
抛出新错误(result.message);
}
})
.catch((错误)=>console.log(错误消息));
}, []);
返回(
菲班克
{CurrencyRates.USD.buy}
{CurrencyRates.USD.sell}
{CurrencyRates.EUR.buy}
{CurrencyRates.EUR.sell}
{CurrencyRates.GBP.buy}
{CurrencyRates.GBP.sell}
);
};
出口违约率;

postman不是internet浏览器,它也不使用设计用于在浏览器中运行的js引擎,因此您不会在postman中获得cors。您的React代码与节点js有关吗?@Anatoly我不理解您的问题。您是否尝试仅从浏览器或后端(NodeJs)请求此url?@DanielManta我知道这一点。问题是,我可以在节点中复制postman请求,以便在响应中获得急需的页面,或者模拟类似浏览器的请求吗?postman不是internet浏览器,它不使用设计用于在浏览器中运行的js引擎,所以你不会在Postmanh中获得cors。你的React代码与节点有什么关系,js?@Anatoly我不明白你的问题。你是否试图仅从浏览器或后端(NodeJs)请求此url?@DanielManta我知道。问题是,我能否以某种方式在节点中复制postman请求,以便在响应中获得急需的页面,或者模拟类似浏览器的请求?