Python Requests 发送 get 请求到 nse india 网站返回 401 响应码。

7
我使用这个程序从https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY获取json数据,但自从今天早上起它就无法工作了,因为它返回<Response [401]>。不过这个链接在Chrome中可以正常加载。有没有办法在不使用Selenium的情况下解决这个问题?
import json
import requests

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
                         'like Gecko) '
                         'Chrome/80.0.3987.149 Safari/537.36',
           'accept-language': 'en,gu;q=0.9,hi;q=0.8', 'accept-encoding': 'gzip, deflate, br'}

res = requests.get("https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY", headers=headers)
print(res)


1
当我尝试在Chrome中打开此链接(https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY)时,出现“未找到资源”的错误。 - Mooncrater
目前对我来说运行良好。 - VarunS2002
对我来说也是同样的错误。如果我运行Python脚本,然后在浏览器中打开URL,它会显示资源未找到。看起来NSE网站正在扫描Python脚本IP并阻止它们。 - TheOnlyAnil
5个回答

24

试试这个:

import requests

baseurl = "https://www.nseindia.com/"
url = f"https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY"
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
                         'like Gecko) '
                         'Chrome/80.0.3987.149 Safari/537.36',
           'accept-language': 'en,gu;q=0.9,hi;q=0.8', 'accept-encoding': 'gzip, deflate, br'}
session = requests.Session()
request = session.get(baseurl, headers=headers, timeout=5)
cookies = dict(request.cookies)
response = session.get(url, headers=headers, timeout=5, cookies=cookies)
print(response.json())

若需多次访问 NSE(api 的)网站,则需在每个后续请求中设置 cookies

response = session.get(url, headers=headers, timeout=5, cookies=cookies)


2
非常感谢VarunS2002,我已经苦苦寻找这个解决方案两天了,而在这里我终于找到了! - sanjay G D
1
如果您感兴趣,可以查看我的项目:https://github.com/VarunS2002/Python-NSE-Option-Chain-Analyzer - VarunS2002
1
这对我来说意义重大✌谢谢 - Devam Sanghvi
我尝试了相同的方法,但是用Java实现。有时候它能正常工作,但是在重复轮询时仍然会出现401响应失败的情况。 - undefined
你能帮我解答这个问题吗?链接在这里:https://stackoverflow.com/questions/77227650/getting-401-unauthorized-even-after-setting-browser-name-and-cookie-in-header - undefined

0

要执行操作,您首先必须执行登录请求调用,该调用将返回会话ID。然后,在下一个请求的头部部分中使用此会话ID进行身份验证并返回有效响应。


请问您能否分享一段代码片段,展示如何在我的程序中实现这个功能? - VarunS2002
请参考此链接:https://developers.onelogin.com/api-docs/1/login-page/create-session-login-token。它展示了如何获取会话令牌,并且同一会话令牌可以在后续的API调用中用于身份验证和交互。 - Akash zawar
NSE不需要登录。 - Abhishake Gupta

0

今天早上我也遇到了同样的错误。以前我只在印度以外的服务器上遇到这个问题。但现在看起来他们试图完全停止爬取。

真的很想找到解决方案。

同时,暂时 旧网站 似乎仍然可以使用。我知道这不是一个永久的解决方案,但我将其用作临时措施,直到找到更长久的解决方案。


是的,旧网站现在还能正常运行,但它随时可能停止,所以必须做好准备。 - VarunS2002

0

使用Java时遇到了相同的错误。 解决方案是

  • 首先连接https://nseindia.com
  • 然后读取服务器返回的cookie。
  • 将相同的cookie添加到您的请求中。

根据您使用的实现来进行ssl调用,您将需要找到适当的方法来获取和设置cookie。 不知道为什么NSE网站在数据已经公开的情况下还要查找cookie。 肯定是NSE应用了一些额外的技术!。


0

我尝试了同样的事情,使用 Node.js 请使用 Node.js IDE 在线 IDE 的链接 请审核我的代码

const axios = require('axios');


let cookie;
let url_oc = "https://www.nseindia.com/option-chain"
let url = "https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY"
let headers = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
  'accept-language': 'en,gu;q=0.9,hi;q=0.8', 'accept-encoding': 'gzip, deflate, br'
}

const instance = axios.create({
  baseURL: url_oc,
  headers: headers,
  cookie: cookie ? cookie : ""
});



const getCookies = async () => {
  try {
    const response = await instance.get(url_oc);
    cookie = response.headers['set-cookie'].join();
  } catch (error) {
    if (error.response.status === 403) {
      console.log("getCookies =========> error.status === 403");
      await getCookies()
    } else {
      console.log("getCookies =========> error");
    }
  }
}


const getAPIData = async () => {
  try {
    if (cookie) {
      const response = await instance.get(url);
      console.log(response.data.records.timestamp);
    }

  } catch (error) {
    if (error.response && error.response.status === 401) {
      console.log("getAPIData =========> error.status === 401");
      if (!cookie) {
        console.log("getAPIData =========> cookie not found");
        await getCookies()
      }
      await getAPIData()
    } else {
      console.log("getAPIData =========> error");
    }
  }
}



(async () => {
  setInterval(async () => {
    await getCookies()
  }, 5000);

  setInterval(async () => {
    await getAPIData()
  }, 3000);
})()

Abhi,你需要Node.js还是Python的代码? 我在上面进行了测试,当时它是可以工作的。 - Raj Shrishrimal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接