首页 > 编程问答 >CS50x2023 Psets9“财务”。获取股票报价时的“查找”功能问题

CS50x2023 Psets9“财务”。获取股票报价时的“查找”功能问题

时间:2024-07-29 04:30:51浏览次数:14  
标签:python flask lookup cs50

我在此任务中的问题是从查找函数获取任何其他“无”输出。经过几天的战斗,我实现了 yt 教程中的代码,精确地为 1 到 1,但它仍然给出相同的结果 - 查找“无”。我不知道我可以在哪里寻找这种行为的根源。下面我附上了我的“quote.html”和@quote应用程序Python代码,用于在本练习中获取股票报价,并在我尝试引用任何符号时查找Python代码和我的终端响应。

Python代码形式app.py :

@app.route("/quote", methods=["GET", "POST"])
@login_required
def quote():
    """Get stock quote."""
    if request.method == "POST":
        symbol = request.form.get("symbol")
        quote = lookup(symbol)
        #if not symbol:
            #return apology("Symbol field can not be empty")
        if not quote:
            return apology("Invalid symbol", 400)
        return render_template("quote.html", quote=quote)
    else:
        return render_template("quote.html")

quote.html 模板:

{% extends "layout.html" %}

{% block title %}
    Quote
{% endblock %}

{% block main %}
    <h2>Get a Stock Quote</h2>
    <form action="{{ url_for('quote') }}" method="post">
        <label for="symbol">Symbol</label>
        <input type="text" id="symbol" name="symbol" placeholder="Symbol">
        <button type="submit">Get Quote</button>
    </form>
    {% if quote %}
        <h3>{{ quote['name'] }} ({{ quote['symbol'] }})</h3>
        <p>Price: {{ quote['price']|usd }}</p>
    {% endif %}
{% endblock %}

查找函数的 Python 代码:

def lookup(symbol):
    """Look up quote for symbol."""

    # Prepare API request
    symbol = symbol.upper()
    end = datetime.datetime.now(pytz.timezone("US/Eastern"))
    start = end - datetime.timedelta(days=7)

    # Yahoo Finance API
    url = (
        f"https://query1.finance.yahoo.com/v7/finance/download/{urllib.parse.quote_plus(symbol)}"
        f"?period1={int(start.timestamp())}"
        f"&period2={int(end.timestamp())}"
        f"&interval=1d&events=history&includeAdjustedClose=true"
    )

    # Query API
    try:
        response = requests.get(url, cookies={"session": str(uuid.uuid4())}, headers={"User-Agent": "python-requests", "Accept": "*/*"})
        response.raise_for_status()

        # CSV header: Date,Open,High,Low,Close,Adj Close,Volume
        quotes = list(csv.DictReader(response.content.decode("utf-8").splitlines()))
        quotes.reverse()
        price = round(float(quotes[0]["Adj Close"]), 2)
        return {
            "name": symbol,
            "price": price,
            "symbol": symbol
        }
    except (requests.RequestException, ValueError, KeyError, IndexError):
        return None

尝试引用任何符号后的终端视图:

finance/ $ flask run
 * Debug mode: off
INFO: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on https://bartosz1tarka-legendary-parakeet-px6wj7xv6vw2655g-5000.app.github.dev
INFO: Press CTRL+C to quit
INFO:  * Restarting with stat
INFO: 127.0.0.1 - - [28/Jul/2024 19:00:23] "GET / HTTP/1.1" 400 -
INFO: 127.0.0.1 - - [28/Jul/2024 19:00:23] "GET /static/styles.css HTTP/1.1" 200 -
INFO: 127.0.0.1 - - [28/Jul/2024 19:00:24] "GET /quote HTTP/1.1" 200 -
INFO: 127.0.0.1 - - [28/Jul/2024 19:00:25] "GET /static/styles.css HTTP/1.1" 200 -
DEBUG: Starting new HTTPS connection (1): query1.finance.yahoo.com:443
DEBUG: https://query1.finance.yahoo.com:443 "GET /v7/finance/download/AAPL?period1=1721581229&period2=1722186029&interval=1d&events=history&includeAdjustedClose=true HTTP/11" 429 19
INFO: 127.0.0.1 - - [28/Jul/2024 19:00:29] "POST /quote HTTP/1.1" 400 -
INFO: 127.0.0.1 - - [28/Jul/2024 19:00:30] "GET /static/styles.css HTTP/1.1" 200 -

我想找出查找函数返回 None 的原因,或者至少我应该在哪里寻找问题。提前致谢。


代码中出现“无效符号”错误的原因是 Yahoo Finance API 对的请求返回了 429 Too Many Requests 状态码。发生这种情况是因为发送到 API 的请求太多,并且超出了其速率限制。

可以通过实现以下更改来解决此问题:

  1. 错误处理: 修改 lookup 函数以正确处理 HTTP 429 错误。

```python def lookup(symbol): """查找符号的报价。"""

   # ...(现有代码)...

   # 查询 API
   try:
       response = requests.get(url, cookies={"session": str(uuid.uuid4())}, headers={"User-Agent": "python-requests", "Accept": "*/*"})
       # 检查状态码是否为 429,如果是,则引发异常
       response.raise_for_status()

       # ...(现有代码)...

   except requests.exceptions.HTTPError as err:
       if err.response.status_code == 429:
           # 处理“请求过多”错误,例如:
           print("Yahoo Finance API 请求过多。请稍后再试。")
           return None
       else:
           # 重新引发其他 HTTP 错误
           raise

```

  1. 缓存: 实现缓存机制以存储 API 响应一段时间。这将减少发送到 Yahoo Finance API 的请求次数。可以使用内存缓存库(如 functools.lru_cache )或持久缓存(如 Redis)。

```python from functools import lru_cache

@lru_cache(maxsize=128) def lookup(symbol): """查找符号的报价。"""

   # ...(现有代码)...

```

  1. 速率限制: 如果需要频繁调用 API,请考虑订阅 Yahoo Finance API 的付费计划,该计划提供更高的速率限制。

通过实现这些更改,可以解决“无效符号”错误并确保的应用程序在速率限制内可靠地从 Yahoo Finance API 检索数据。请记住要负责任地处理 API 并遵守其使用条款。

标签:python,flask,lookup,cs50
From: 78804361

相关文章