ZhuLinsen/daily_stock_analysis · error · DataFetchError

Akshare 获取美股数据失败: {e}

Error message

Akshare 获取美股数据失败: {e}

What it means

Raised by AkshareFetcher._fetch_us_data when ak.stock_us_daily fails with an exception that is NOT a detected rate-limit (no 'banned'/'blocked'/'频率'/'rate'/'限制' in the message). It is the generic DataFetchError escape hatch wrapping the underlying Sina/akshare exception, designed so DataFetcherManager can fall back to another US data source (Yfinance, AlphaVantage).

Source

Thrown at data_provider/akshare_fetcher.py:821

                if '成交量' in df.columns and '收盘' in df.columns:
                    df['成交额'] = df['成交量'] * df['收盘']
                else:
                    df['成交额'] = 0
                
                return df
            else:
                logger.warning(f"[API返回] ak.stock_us_daily 返回空数据, 耗时 {api_elapsed:.2f}s")
                return pd.DataFrame()
            
        except Exception as e:
            error_msg = str(e).lower()
            
            # 检测反爬封禁
            if any(keyword in error_msg for keyword in ['banned', 'blocked', '频率', 'rate', '限制']):
                logger.warning(f"检测到可能被封禁: {e}")
                raise RateLimitError(f"Akshare 可能被限流: {e}") from e
            
            raise DataFetchError(f"Akshare 获取美股数据失败: {e}") from e

    def _fetch_hk_data(self, stock_code: str, start_date: str, end_date: str) -> pd.DataFrame:
        """
        获取港股历史数据
        
        数据来源:ak.stock_hk_hist()
        
        Args:
            stock_code: 港股代码,如 '00700', '01810'
            start_date: 开始日期,格式 'YYYY-MM-DD'
            end_date: 结束日期,格式 'YYYY-MM-DD'
            
        Returns:
            港股历史数据 DataFrame
        """
        import akshare as ak
        
        # 防封禁策略 1: 随机 User-Agent

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Log e.__cause__ to identify whether it is KeyError (payload shape change → pin akshare version), timeout (network), or HTTP error.
  2. Verify the ticker exists on Sina Finance US quotes before blaming the fetcher.
  3. If akshare changed the interface, upgrade/pin akshare to a compatible release and rerun.
  4. Rely on the manager's fallback to YfinanceFetcher for US symbols.

Example fix

// before
try:
    df = akshare_fetcher.fetch('AMD', start, end)
except DataFetchError:
    raise  # whole job dies

// after
try:
    df = akshare_fetcher.fetch('AMD', start, end)
except DataFetchError as e:
    logger.warning('akshare US failed: %s, falling back', e)
    df = yfinance_fetcher.fetch('AMD', start, end)
Defensive patterns

Strategy: fallback

Validate before calling

import akshare as ak
# verify Sina US coverage for the symbol first
spot = ak.stock_us_spot()  # or a cheap single-symbol call
assert 'AMD' in spot['symbol'].str.upper().values

Try / catch

try:
    df = akshare_fetcher.fetch(us_sym, start, end)
except DataFetchError as e:
    logger.warning('akshare US failed for %s: %s', us_sym, e)
    df = yfinance_fetcher.fetch(us_sym, start, end)

Prevention

When it happens

Trigger: Fetching a US ticker like 'AMD' when Sina's endpoint is down, the ticker is unknown to Sina (empty/broken payload raising inside akshare), a network timeout, or an akshare version change to stock_us_daily's return shape. Note: an empty-but-clean response returns an empty DataFrame instead; this error means an actual exception was raised.

Common situations: akshare upgraded and stock_us_daily signature/return changed; delisted or exotic tickers (e.g. OTC symbols) that Sina does not cover; corporate-VPN TLS interception breaking the Sina connection.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/1a0aae043f02eb39. Report an issue: GitHub.