You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从谷歌学术提取论文原始链接的Python代码报错修复求助

谷歌学术论文原始链接提取及JSONDecodeError修复方案

问题背景

  • 现有代码仅能抓取谷歌学术作者页前20条内部嵌套链接,无法获取期刊原始链接
  • 复用原函数访问单篇论文详情链接时,触发JSONDecodeError,无法解析页面内容

报错根源

原函数采用POST请求并传入json=1参数,这个逻辑仅适配谷歌学术作者页的批量加载接口。但单篇论文详情页返回的是普通HTML页面,并非JSON格式数据,直接调用r.json()必然解析失败。

完整修复代码

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd

def fetch_author_paper_links(url: str) -> pd.DataFrame:
    """从谷歌学术作者页获取所有论文的详情页链接(支持加载更多)"""
    pd.set_option('display.max_columns', None)
    pd.set_option('display.max_colwidth', None)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
    }
    session = requests.Session()
    session.headers.update(headers)
    
    all_paper_links = []
    start = 0
    
    while True:
        # 构造加载更多的请求参数
        payload = {
            'json': '1',
            'start': start
        }
        response = session.post(url, data=payload)
        if not response.json().get('B'):
            break  # 没有更多内容时停止
        
        soup = bs(response.json()['B'], 'html.parser')
        # 提取论文详情页链接
        paper_links = [
            f"https://scholar.google.com{x.get('href')}"
            for x in soup.select('a.gs_or_cit')
            if x.get('href') and 'view_citation' in x.get('href')
        ]
        all_paper_links.extend(paper_links)
        start += 20  # 每次加载20条
    
    return pd.DataFrame(all_paper_links, columns=['Paper_Detail_Link'])

def fetch_original_paper_url(paper_detail_url: str, session: requests.Session) -> str:
    """从论文详情页提取期刊原始链接"""
    response = session.get(paper_detail_url)
    soup = bs(response.text, 'html.parser')
    
    # 查找原始链接(谷歌学术中原始链接通常带有"href"且指向期刊网站)
    original_link = None
    for link in soup.select('a.gs_or_sv_link'):
        href = link.get('href')
        if href and not href.startswith('https://scholar.google.com'):
            original_link = href
            break
    
    # 备用:如果没有找到直接链接,尝试查找指向PDF或期刊的其他链接
    if not original_link:
        for link in soup.select('a'):
            href = link.get('href')
            if href and ('.pdf' in href or 'proceedings' in href or 'journal' in href):
                if not href.startswith('https://scholar.google.com'):
                    original_link = href
                    break
    
    return original_link if original_link else 'No original link found'

# 主逻辑
if __name__ == '__main__':
    author_url = 'https://scholar.google.ca/citations?user=iYN86KEAAAAJ&hl=en'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
    }
    session = requests.Session()
    session.headers.update(headers)
    
    # 获取所有论文详情页链接
    df_papers = fetch_author_paper_links(author_url)
    
    # 遍历提取原始链接
    df_papers['Original_Link'] = df_papers['Paper_Detail_Link'].apply(
        lambda x: fetch_original_paper_url(x, session)
    )
    
    print(df_papers)
    # 保存结果到CSV
    df_papers.to_csv('scholar_original_links.csv', index=False)

代码说明

  1. 作者页处理:通过循环start参数,模拟加载更多内容,获取作者所有论文的详情页链接,解决仅返回前20条的问题
  2. 详情页处理:改用GET请求解析HTML,通过定位谷歌学术中原始链接的特征标签(gs_or_sv_link)提取期刊原始链接,同时增加备用逻辑提高成功率
  3. 会话复用:复用requests.Session保持会话状态,避免重复建立连接,同时减少被反爬拦截的概率

内容的提问来源于stack exchange,提问作者BostonPlummer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 01:34:52