admin管理员组文章数量:1530031
1.假定我们现在有一个参考文献列表,该如何从这些参考文献中快速提取参考文献的论文标题呢?
一开始,我想通过正则表达式的方法从参考文献中提取标题信息,例如:
1.对于中文参考文献,可以遍历每一个字符,从出现一个“.”开始,到出现下一个“."或者“[”符号结束,则中间的内容为该参考文献的标题,代码如下:
# 判断是否为中文参考文献或英文参考文献
for char in f:
if '\u4e00' <= char <= '\u9fff': # 中文字符范围
# 提取第一个 . 号后的部分
part = f.split('.', 1)[1]
# 提取标题,直到出现 [ 符号或者 . 符号
title = re.split(r'\[|\.', part)[0].strip()
break
2.对于英文标题,一开始想的是遍历该条参考文献的字符,找到三个连续的英文单词,如果存在,则从找到的第一个单词开始向左直到遇到 `.` 或 `]`,向右直到遇到 `.` 或 `[` 结束。
elif 'A' <= char <= 'Z' or 'a' <= char <= 'z': # 英文字母范围
words_and_symbols = re.findall(r'\b\w+\b|\S', f)
print(words_and_symbols)
title = 'Null'
for i in range(len(words_and_symbols) - 2):
if (re.match(r'[a-z]', words_and_symbols[i]) and
re.match(r'[a-z]', words_and_symbols[i + 1]) and
re.match(r'[a-z]', words_and_symbols[i + 2])):
# 从找到的第一个单词开始向左直到遇到 `.` 或 `]`,向右直到遇到 `.` 或 `[`
start_idx = i
while start_idx > 0 and words_and_symbols[start_idx - 1] not in ['.', ']']:
start_idx -= 1
end_idx = i + 3
while end_idx < len(words_and_symbols) and words_and_symbols[end_idx] not in ['.', '[']:
end_idx += 1
title = ' '.join(words_and_symbols[start_idx:end_idx]).strip()
break
奈何英文参考文献的格式千奇百怪,例如有的作者名字可能是4个英文单词组成,而有的标题可能只有三个连续的英文单词组成,就会导致标题被错误提取,想了两天也没有想到比较完美的判断方法。
2.通过chatgpt获取参考文献的标题
将参考文献列表输入到chatgpt中,并让他提取文献标题,它能够快速、准确的帮我提取参考文献的信息。
于是,我通过调用api的方法,实现了参考文献的信息提取,参考代码如下:
import csv
import json
import re
import requests
import pandas as pd
API_KEY = "你的openai key"
API_URL = "你的api网址"
def extract_title_from_references(references_content, prompt):
"""
使用 OpenAI API 提取参考文献中的信息。
"""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}"
}
data = {
"model": "gpt-4o-mini-2024-07-18",
"messages": [
{"role": "system", "content": "你是一个可以提取文献信息的助手。"},
{"role": "user", "content": prompt + references_content}
],
"max_tokens": 2000,
"temperature": 0.5
}
response = requests.post(f"{API_URL}/chat/completions", headers=headers, data=json.dumps(data))
response_json = response.json()
info = response_json['choices'][0]['message']['content'].strip().split('\n')
return info
def GetInfo(references_content):
"""
提取参考文献中的标题、DOI 和 arXiv 信息,并判断文献类型。
"""
# 将 references_content 拆分为每组 60 行
lines = references_content.split('\n')
grouped_content = ['\n'.join(lines[i:i+60]) for i in range(0, len(lines), 60)]
all_titles = []
for group in grouped_content:
title_prompt = "请你帮我将每一个参考文献的标题提取出来,注意,输出结果只要参考文献的标题,如果找不到标题,输出NULL,每个输出结果占一行\n"
titles = extract_title_from_references(group, title_prompt)
all_titles.extend(titles)
# 清除标题前后的空白字符串
all_titles = [title.strip() for title in all_titles]
doilist = []
arxivlist = []
for f in references_content.split('\n'):
# DOI
try:
if 'doi' in f:
DOI = f.split('org/')[1].strip()
elif 'doi:' in f:
DOI = f.split('doi:')[1].strip()
else:
DOI = 'Null'
except:
DOI = 'Null'
doilist.append(DOI)
# arXiv
try:
if 'arXiv' in f:
arxiv_match = re.search(r'arXiv.*?(\d{4}\.\d{5})', f)
if arxiv_match:
arxiv = arxiv_match.group(1).strip()
else:
arxiv = 'Null'
else:
arxiv = 'Null'
except:
arxiv = 'Null'
arxivlist.append(arxiv)
# Debugging output
print(f"Total titles: {len(all_titles)}")
print(f"Total DOIs: {len(doilist)}")
print(f"Total arXiv IDs: {len(arxivlist)}")
# 判断文献类型
typelist = []
for title in all_titles:
if re.search(r'[\u4e00-\u9fff]', title):
typelist.append('中文文献')
else:
typelist.append('英文文献')
refdata = {
'Title': all_titles,
'DOI': doilist,
'arXiv': arxivlist,
'Type': typelist
}
refdata = pd.DataFrame(refdata)
return refdata
通过这种方式,能够高效的提取参考文献的信息,我还提取了参考文献的doi/arxiv号,当然这部分可以通过表达式去获取。
本代码采用pt-4o-mini-2024-07-18模型,api价格是openai开发的api中价格最低的,经过测试,提取300条参考文献消耗约0.06美元的额度,精度在98%以上,除了一些特别特殊的参考文献除外。例如:
或许通过增强prompt可以进一步提高识别率。
识别完每条参考文献之后,我们就可以通过爬取百度学术,获取每条参考文献的doi号,在scihub中进行批量下载。(开发中)
版权声明:本文标题:python通过调用OPENAI API(ChatGPT)快速提取参考文献的标题信息 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1726698342a1081329.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论