从谷歌学术提取论文原始链接的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)
代码说明
- 作者页处理:通过循环
start参数,模拟加载更多内容,获取作者所有论文的详情页链接,解决仅返回前20条的问题 - 详情页处理:改用
GET请求解析HTML,通过定位谷歌学术中原始链接的特征标签(gs_or_sv_link)提取期刊原始链接,同时增加备用逻辑提高成功率 - 会话复用:复用
requests.Session保持会话状态,避免重复建立连接,同时减少被反爬拦截的概率
内容的提问来源于stack exchange,提问作者BostonPlummer
相关产品推荐
相关产品推荐

