{"record":{"id":"19f92031ea9099c1","repo":"binary-husky/gpt_academic","slug":"error-19f920","errorCode":null,"errorMessage":"所有可用镜像站点均无法完成下载","messagePattern":"所有可用镜像站点均无法完成下载","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"crazy_functions/review_fns/data_sources/scihub_source.py","lineNumber":142,"sourceCode":"                    mirror,\n                    headers=self.headers,\n                    data=self.payload,\n                    proxies=self.proxies,\n                    timeout=self.timeout\n                )\n                if res.ok:\n                    logger.info(f\"成功使用镜像站点: {mirror}\")\n                    self.url = mirror  # 更新当前使用的镜像\n                    time.sleep(1)  # 降低等待时间以提高效率\n                    return res\n            except Exception as e:\n                logger.error(f\"尝试镜像 {mirror} 失败: {str(e)}\")\n                last_exception = e\n                continue\n\n        if last_exception:\n            raise last_exception\n        raise Exception(\"所有可用镜像站点均无法完成下载\")\n\n    def _extract_url(self, response):\n        \"\"\"从响应中提取PDF下载链接\"\"\"\n        soup = BeautifulSoup(response.content, 'html.parser')\n        try:\n            # 尝试多种方式提取PDF链接\n            pdf_element = soup.find(id='pdf')\n            if pdf_element:\n                content_url = pdf_element.get('src')\n            else:\n                # 尝试其他可能的选择器\n                pdf_element = soup.find('iframe')\n                if pdf_element:\n                    content_url = pdf_element.get('src')\n                else:\n                    # 查找直接的PDF链接\n                    pdf_links = soup.find_all('a', href=lambda x: x and '.pdf' in x)\n                    if pdf_links:","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/review_fns/data_sources/scihub_source.py#L124-L160","documentation":"Raised after the loop over working mirrors completes without a single successful download response: every mirror that passed the health check nonetheless failed during the actual POST (exception, non-ok status, or captcha/HTML instead of the PDF). If individual exceptions were recorded, the last one is re-raised instead; this generic Exception only appears when all mirrors returned res.ok == False without raising.","triggerScenarios":"Mirrors respond 200 to the health check but return 403/502/redirect-to-captcha for the real DOI POST; SciHub rate-limits the IP after the probe burst; the payload/DOI is not resolvable so every mirror answers an error page; proxies drop long POSTs.","commonSituations":"Scihub serving Cloudflare challenges to datacenter IPs; a DOI that SciHub does not have in its repository; stale mirror URLs that now park/redirect; aggressive probing (5 mirrors) triggering rate limits before the real download.","solutions":["Inspect logger.error lines just before the raise — they show each mirror's failure reason (status code vs exception).","Add delay/backoff between probe and download, or reduce the probe burst, to avoid tripping rate limits.","Verify the DOI actually exists on SciHub by opening a mirror in a browser with the same DOI.","Rotate exit IP (different proxy) or try again later; fall back to the arXiv/open-access source for the paper."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    res = scihub._fetch_from_mirrors()\nexcept Exception as e:\n    msg = str(e)\n    if '所有可用镜像站点均无法完成下载' in msg or '尝试镜像' in msg:\n        time.sleep(30)\n        return scihub.download(doi, attempt=retry_no + 1)  # outer backoff\n    raise","preventionTips":["Space out probe and download calls to avoid tripping rate limits on all mirrors at once.","Log which mirror failed with which status — patterns (all 403) point to IP blocking, not bad DOIs.","Verify the DOI exists on SciHub before automating bulk downloads."],"tags":["scihub","mirrors","rate-limit","download","network"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}