fix: 优化论文爬取功能

- papers_crawler.py: 优化CSV下载参数默认值为"yes",提升用户体验
- src/crawler.py:
  * 修复摘要字段换行符处理,确保数据清洁性
  * 增强MedRxiv PDF链接获取策略,支持多种URL格式和版本号
This commit is contained in:
iomgaa 2025-08-24 15:07:34 +08:00
parent 367696788b
commit 8d6d217c2f
2 changed files with 35 additions and 27 deletions

View File

@ -38,7 +38,7 @@ def setup_args():
parser.add_argument( parser.add_argument(
'--csv-download', '--csv-download',
type=str, type=str,
default=None, default="yes",
help='指定CSV文件路径' help='指定CSV文件路径'
) )

View File

@ -240,7 +240,7 @@ class PaperCrawler:
return { return {
'title': paper_data.get('title', '').strip(), 'title': paper_data.get('title', '').strip(),
'authors': ', '.join(paper_data.get('authors', [])), 'authors': ', '.join(paper_data.get('authors', [])),
'abstract': paper_data.get('summary', '').strip(), 'abstract': paper_data.get('summary', '').strip().replace('\n', ' ').replace('\r', ' '),
'doi': paper_data.get('doi', ''), 'doi': paper_data.get('doi', ''),
'published_date': paper_data.get('published', '').split('T')[0] if 'T' in paper_data.get('published', '') else paper_data.get('published', ''), 'published_date': paper_data.get('published', '').split('T')[0] if 'T' in paper_data.get('published', '') else paper_data.get('published', ''),
'url': paper_data.get('link', ''), 'url': paper_data.get('link', ''),
@ -251,7 +251,7 @@ class PaperCrawler:
return { return {
'title': paper_data.get('title', '').strip(), 'title': paper_data.get('title', '').strip(),
'authors': paper_data.get('authors', ''), 'authors': paper_data.get('authors', ''),
'abstract': paper_data.get('abstract', '').strip(), 'abstract': paper_data.get('abstract', '').strip().replace('\n', ' ').replace('\r', ' '),
'doi': paper_data.get('doi', ''), 'doi': paper_data.get('doi', ''),
'published_date': paper_data.get('date', ''), 'published_date': paper_data.get('date', ''),
'url': f"https://doi.org/{paper_data.get('doi', '')}" if paper_data.get('doi') else '', 'url': f"https://doi.org/{paper_data.get('doi', '')}" if paper_data.get('doi') else '',
@ -626,7 +626,7 @@ class PaperCrawler:
return None return None
def _get_medrxiv_pdf_url(self, doi: str, url: str) -> Optional[str]: def _get_medrxiv_pdf_url(self, doi: str, url: str) -> Optional[str]:
"""获取MedRxiv论文PDF链接 """获取MedRxiv论文PDF链接 - 支持多种URL格式策略
Args: Args:
doi (str): 论文DOI doi (str): 论文DOI
@ -640,30 +640,38 @@ class PaperCrawler:
logging.warning("MedRxiv论文缺少DOI") logging.warning("MedRxiv论文缺少DOI")
return None return None
# 主策略基于DOI构造PDF链接 if not doi.startswith('10.1101/'):
# DOI格式: 10.1101/yyyy.mm.dd.xxxxxxx logging.warning(f"不支持的MedRxiv DOI格式: {doi}")
# PDF格式: https://www.medrxiv.org/content/medrxiv/early/yyyy/mm/dd/yyyy.mm.dd.xxxxxxx.full.pdf return None
if doi.startswith('10.1101/'): # 提取DOI后缀部分
# 提取日期和论文ID部分
paper_part = doi.replace('10.1101/', '') paper_part = doi.replace('10.1101/', '')
# 解析日期部分 yyyy.mm.dd.xxxxxxx # 策略1尝试简洁版本号格式优先级最高
# 格式https://www.medrxiv.org/content/10.1101/yyyy.mm.dd.xxxxxxxvN.full.pdf
for version in ['v1', 'v2', 'v3']: # 常见版本号
simple_url = f"https://www.medrxiv.org/content/10.1101/{paper_part}{version}.full.pdf"
logging.debug(f"尝试MedRxiv简洁格式: {simple_url}")
# 这里可以添加URL可用性检查暂时先返回第一个尝试
# 实际使用时下载函数会验证URL的有效性
if version == 'v1': # 优先返回v1版本
return simple_url
# 策略2回退到早期访问格式复杂路径
# 格式https://www.medrxiv.org/content/medrxiv/early/yyyy/mm/dd/yyyy.mm.dd.xxxxxxx.full.pdf
parts = paper_part.split('.') parts = paper_part.split('.')
if len(parts) >= 4: if len(parts) >= 4:
year = parts[0] year = parts[0]
month = parts[1].zfill(2) # 确保两位数 month = parts[1].zfill(2) # 确保两位数
day = parts[2].zfill(2) # 确保两位数 day = parts[2].zfill(2) # 确保两位数
# 构造PDF URL # 构造复杂格式PDF URL
pdf_url = f"https://www.medrxiv.org/content/medrxiv/early/{year}/{month}/{day}/{paper_part}.full.pdf" complex_url = f"https://www.medrxiv.org/content/medrxiv/early/{year}/{month}/{day}/{paper_part}.full.pdf"
logging.debug(f"MedRxiv PDF链接: {pdf_url}") logging.debug(f"回退使用MedRxiv复杂格式: {complex_url}")
return pdf_url return complex_url
else: else:
logging.warning(f"无法解析MedRxiv DOI格式: {doi}") logging.warning(f"无法解析MedRxiv DOI日期格式: {doi}")
return None
else:
logging.warning(f"不支持的MedRxiv DOI格式: {doi}")
return None return None
except Exception as e: except Exception as e: