Java Yahoo Finance HTTP响应代码:401用于URL
我试图创建一个程序,从Yahoo Finance下载历史数据,然后根据主类中输入的股票符号显示去年的历史数据 由于某种原因,当我试图运行我的程序时,我总是得到一个401代码。如果我复制并粘贴到浏览器中,401错误中显示的URL会告诉我要去哪里 我不知道我做错了什么 下面是我的StockDownloader类代码:Java Yahoo Finance HTTP响应代码:401用于URL,java,Java,我试图创建一个程序,从Yahoo Finance下载历史数据,然后根据主类中输入的股票符号显示去年的历史数据 由于某种原因,当我试图运行我的程序时,我总是得到一个401代码。如果我复制并粘贴到浏览器中,401错误中显示的URL会告诉我要去哪里 我不知道我做错了什么 下面是我的StockDownloader类代码: import java.util.GregorianCalendar; import java.util.Calendar; import java.util.ArrayList; i
import java.util.GregorianCalendar;
import java.util.Calendar;
import java.util.ArrayList;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;
public class StockDownloader
{
public static final int DATE = 0;
public static final int OPEN = 1;
public static final int HIGH = 2;
public static final int LOW = 3;
public static final int CLOSE = 4;
public static final int VOLUME = 6;
public static final int ADJCLOSE = 5;
private ArrayList<GregorianCalendar> dates;
private ArrayList<Double> opens;
private ArrayList<Double> highs;
private ArrayList<Double> lows;
private ArrayList<Double> closes;
private ArrayList<Integer> volumes;
private ArrayList<Double> adjCloses;
public StockDownloader (String symbol)
{
dates = new ArrayList<GregorianCalendar>();
opens = new ArrayList<Double>();
highs = new ArrayList<Double>();
lows = new ArrayList<Double>();
closes = new ArrayList<Double>();
volumes = new ArrayList<Integer>();
adjCloses = new ArrayList<Double>();
//https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI
String url = "https://query1.finance.yahoo.com/v7/finance/download/"+symbol+"?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI";
try
{
URL yhoofin = new URL(url);
URLConnection data = yhoofin.openConnection();
Scanner input = new Scanner(data.getInputStream());
if(input.hasNext())//skip line...it's just the header
input.nextLine();
//start reading data
while(input.hasNextLine())
{
String line = input.nextLine();
//TODO- connec tdata to the correct ArrayList
System.out.println(line);
}
}
catch (Exception e)
{
System.err.println(e);
}
}
public ArrayList<GregorianCalendar> getDates()
{
return dates;
}
/*public ArrayList<Double> get Opens()
{
}*/
}
请帮助401错误代码表示用户未经授权。再看一次,如果你确信你所做的一切都是正确的,但问题仍然存在,那么看看这个。这使得使用Yahoo Finance API更容易。看起来Yahoo已经改变了访问Finance API的方式。您需要将cookie添加到URL连接。已经更改了你的代码,它对我有效
public class StockDownloader {
public static final int DATE = 0;
public static final int OPEN = 1;
public static final int HIGH = 2;
public static final int LOW = 3;
public static final int CLOSE = 4;
public static final int VOLUME = 6;
public static final int ADJCLOSE = 5;
private ArrayList<GregorianCalendar> dates;
private ArrayList<Double> opens;
private ArrayList<Double> highs;
private ArrayList<Double> lows;
private ArrayList<Double> closes;
private ArrayList<Integer> volumes;
private ArrayList<Double> adjCloses;
private String finalCrumb;
public StockDownloader(String symbol) {
dates = new ArrayList<GregorianCalendar>();
opens = new ArrayList<Double>();
highs = new ArrayList<Double>();
lows = new ArrayList<Double>();
closes = new ArrayList<Double>();
volumes = new ArrayList<Integer>();
adjCloses = new ArrayList<Double>();
try {
// Hit the below URL to get the cookies and the crumb value to access the finance API
String mainURL = "https://uk.finance.yahoo.com/quote/"+symbol+"/history";
Map<String, List<String>> setCookies = setCookies(mainURL);
// https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI
// will need to append the crumb in the end to the below URL to have the actual crumb rather than the hardcoded one
String url = "https://query1.finance.yahoo.com/v7/finance/download/" + symbol
+ "?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=" + finalCrumb;
URL yhoofin = new URL(url);
URLConnection data = yhoofin.openConnection();
// get the list of Set-Cookie cookies from response headers
List<String> cookies = setCookies.get("Set-Cookie");
if (cookies != null) {
for (String c : cookies)
data.setRequestProperty("Cookie", c);
}
Scanner input = new Scanner(data.getInputStream());
if (input.hasNext())// skip line...it's just the header
input.nextLine();
// start reading data
while (input.hasNextLine()) {
String line = input.nextLine();
// TODO- connec tdata to the correct ArrayList
System.out.println(line);
}
input.close();
}
catch (Exception e) {
System.err.println(e);
}
}
// This method extracts the crumb and is being called from setCookies() method
private String searchCrumb(URLConnection con) throws IOException {
String crumb = null;
InputStream inStream = con.getInputStream();
InputStreamReader irdr = new InputStreamReader(inStream);
BufferedReader rsv = new BufferedReader(irdr);
Pattern crumbPattern = Pattern.compile(".*\"CrumbStore\":\\{\"crumb\":\"([^\"]+)\"\\}.*");
String line = null;
while (crumb == null && (line = rsv.readLine()) != null) {
Matcher matcher = crumbPattern.matcher(line);
if (matcher.matches())
crumb = matcher.group(1);
}
rsv.close();
System.out.println("Crumb is : "+crumb);
return crumb;
}
// This method extracts the cookies from response headers and passes the same con object to searchCrumb()
// method to extract the crumb and set the crumb value in finalCrumb global variable
private Map<String, List<String>> setCookies(String mainUrl) throws IOException {
// "https://finance.yahoo.com/quote/SPY";
Map<String, List<String>> map = new HashMap<String, List<String>>();
URL url = new URL(mainUrl);
URLConnection con = url.openConnection();
finalCrumb = searchCrumb(con);
for (Map.Entry<String, List<String>> entry : con.getHeaderFields().entrySet()) {
if (entry.getKey() == null || !entry.getKey().equals("Set-Cookie"))
continue;
for (String s : entry.getValue()) {
map.put(entry.getKey(), entry.getValue());
System.out.println(map);
}
}
return map;
}
public ArrayList<GregorianCalendar> getDates() {
return dates;
}
}
公共类股票下载程序{
公共静态最终整数日期=0;
公共静态最终int OPEN=1;
公共静态最终int高=2;
公共静态最终int低=3;
公共静态最终int CLOSE=4;
公共静态最终整数卷=6;
公共静态最终int ADJCLOSE=5;
私人ArrayList日期;
私人ArrayList打开;
私人ArrayList高点;
私人ArrayList lows;
私人ArrayList关闭;
私有ArrayList卷;
私有数组列表;
私有字符串finalCrumb;
公共股票下载器(字符串符号){
日期=新的ArrayList();
打开=新建ArrayList();
highs=新的ArrayList();
lows=新的ArrayList();
closes=新建ArrayList();
卷=新的ArrayList();
adjCloses=newarraylist();
试一试{
//点击下面的URL获取cookies和crump值以访问finance API
字符串mainURL=”https://uk.finance.yahoo.com/quote/“+符号+”/历史记录”;
Map setCookies=setCookies(mainURL);
// https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI
//将需要在下面的URL末尾添加面包屑,以获得实际的面包屑,而不是硬编码的面包屑
字符串url=”https://query1.finance.yahoo.com/v7/finance/download/“+符号
+“?周期1=1467352800,周期2=149888800,周期=1d,事件=history&crumb=“+finalCrumb;
URL yhoofin=新URL(URL);
URLConnection data=yhoofin.openConnection();
//从响应头获取集合Cookie的列表
List cookies=setCookies.get(“Set Cookie”);
如果(cookies!=null){
用于(字符串c:cookies)
setRequestProperty(“Cookie”,c);
}
扫描仪输入=新扫描仪(data.getInputStream());
if(input.hasNext())//跳过行…它只是标题
input.nextLine();
//开始读取数据
while(input.hasNextLine()){
String line=input.nextLine();
//TODO-将tdata连接到正确的ArrayList
系统输出打印项次(行);
}
input.close();
}
捕获(例外e){
系统错误println(e);
}
}
//此方法提取碎屑,并从setCookies()方法调用
私有字符串searchCramp(URLConnection con)引发IOException{
字符串crump=null;
InputStream inStream=con.getInputStream();
InputStreamReader irdr=新的InputStreamReader(流内);
BufferedReader rsv=新的BufferedReader(irdr);
Pattern-crumbPattern=Pattern.compile(“.*\'crumpstore\”:\\{\'crump\”:\”([^\“]+)\“\\}.*);
字符串行=null;
而(crumb==null&(line=rsv.readLine())!=null){
Matcher Matcher=rumbpattern.Matcher(线);
if(matcher.matches())
crumb=matcher.组(1);
}
rsv.close();
System.out.println(“Crumb是:“+Crumb”);
返回面包屑;
}
//此方法从响应头中提取cookie,并将相同的con对象传递给searchCrumb()
//方法提取碎屑并在finalCrumb全局变量中设置碎屑值
私有映射集cookies(字符串mainUrl)引发IOException{
// "https://finance.yahoo.com/quote/SPY";
Map Map=newhashmap();
URL=新URL(mainUrl);
URLConnection con=url.openConnection();
finalCrumb=搜索碎屑(con);
对于(Map.Entry:con.getHeaderFields().entrySet()){
if(entry.getKey()==null | |!entry.getKey().equals(“设置Cookie”))
继续;
对于(字符串s:entry.getValue()){
map.put(entry.getKey(),entry.getValue());
系统输出打印项次(map);
}
}
返回图;
}
公共数组列表getDates(){
返回日期;
}
}
我们已经获得了很多关于财务API的详细信息
试一试!您查过代码401的含义吗?这告诉您什么?如果我的答案对您有所帮助,请随意将其标记为答案!
public class StockDownloader {
public static final int DATE = 0;
public static final int OPEN = 1;
public static final int HIGH = 2;
public static final int LOW = 3;
public static final int CLOSE = 4;
public static final int VOLUME = 6;
public static final int ADJCLOSE = 5;
private ArrayList<GregorianCalendar> dates;
private ArrayList<Double> opens;
private ArrayList<Double> highs;
private ArrayList<Double> lows;
private ArrayList<Double> closes;
private ArrayList<Integer> volumes;
private ArrayList<Double> adjCloses;
private String finalCrumb;
public StockDownloader(String symbol) {
dates = new ArrayList<GregorianCalendar>();
opens = new ArrayList<Double>();
highs = new ArrayList<Double>();
lows = new ArrayList<Double>();
closes = new ArrayList<Double>();
volumes = new ArrayList<Integer>();
adjCloses = new ArrayList<Double>();
try {
// Hit the below URL to get the cookies and the crumb value to access the finance API
String mainURL = "https://uk.finance.yahoo.com/quote/"+symbol+"/history";
Map<String, List<String>> setCookies = setCookies(mainURL);
// https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI
// will need to append the crumb in the end to the below URL to have the actual crumb rather than the hardcoded one
String url = "https://query1.finance.yahoo.com/v7/finance/download/" + symbol
+ "?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=" + finalCrumb;
URL yhoofin = new URL(url);
URLConnection data = yhoofin.openConnection();
// get the list of Set-Cookie cookies from response headers
List<String> cookies = setCookies.get("Set-Cookie");
if (cookies != null) {
for (String c : cookies)
data.setRequestProperty("Cookie", c);
}
Scanner input = new Scanner(data.getInputStream());
if (input.hasNext())// skip line...it's just the header
input.nextLine();
// start reading data
while (input.hasNextLine()) {
String line = input.nextLine();
// TODO- connec tdata to the correct ArrayList
System.out.println(line);
}
input.close();
}
catch (Exception e) {
System.err.println(e);
}
}
// This method extracts the crumb and is being called from setCookies() method
private String searchCrumb(URLConnection con) throws IOException {
String crumb = null;
InputStream inStream = con.getInputStream();
InputStreamReader irdr = new InputStreamReader(inStream);
BufferedReader rsv = new BufferedReader(irdr);
Pattern crumbPattern = Pattern.compile(".*\"CrumbStore\":\\{\"crumb\":\"([^\"]+)\"\\}.*");
String line = null;
while (crumb == null && (line = rsv.readLine()) != null) {
Matcher matcher = crumbPattern.matcher(line);
if (matcher.matches())
crumb = matcher.group(1);
}
rsv.close();
System.out.println("Crumb is : "+crumb);
return crumb;
}
// This method extracts the cookies from response headers and passes the same con object to searchCrumb()
// method to extract the crumb and set the crumb value in finalCrumb global variable
private Map<String, List<String>> setCookies(String mainUrl) throws IOException {
// "https://finance.yahoo.com/quote/SPY";
Map<String, List<String>> map = new HashMap<String, List<String>>();
URL url = new URL(mainUrl);
URLConnection con = url.openConnection();
finalCrumb = searchCrumb(con);
for (Map.Entry<String, List<String>> entry : con.getHeaderFields().entrySet()) {
if (entry.getKey() == null || !entry.getKey().equals("Set-Cookie"))
continue;
for (String s : entry.getValue()) {
map.put(entry.getKey(), entry.getValue());
System.out.println(map);
}
}
return map;
}
public ArrayList<GregorianCalendar> getDates() {
return dates;
}
}