基于BeautifulSoup实现pubmed文献摘要的爬虫与无格式输出
一、实现背景
以构建项目所需的数据集为目标,我们开发了一套基于Python语言的文献摘要爬取工具。该工具不仅可以通过PyCharm快速配置和运行,并且能够利用BeautifulSoup库有效地解析网页源码。最终输出结果为纯文本文件,在每个文件中都标注了对应的PubMed标识符作为文件名
二、具体实现
具体代码如下:
该代码具备单关键字查询功能以及多关键字AND查询操作,并同时保证了输出文章数量的一致性与明确性。
在处理多关键字的AND查找操作时,在多个关键字之间应添加分号;而在命令行界面中,则需以' %3b '的形式替代传统的分号符号;可参考相关资料进一步了解这一操作的具体应用及其意义。
import requests
import re
import os
from bs4 import BeautifulSoup
key = input("请输入你想查找的信息:")
local_folder = input("请输入你想存储的文件夹位置:")
if not os.path.exists(local_folder):
os.makedirs(local_folder)
turl = "https://pubmed.ncbi.nlm.nih.gov/"
tdata = requests.get(turl, params={"term": key}).text
pat_alldocu = '<span class="value">(.*?)</span>'
alldocu = re.compile(pat_alldocu, re.S).findall(tdata)
num = int(input("请输入大致想获取的文章数目(总数为" + str(alldocu[0]) + "):"))
downloaded_count = 0 # 记录已下载的文章数
for j in range(0, (num - 1) // 10 + 1):
url = f"https://pubmed.ncbi.nlm.nih.gov/?term={key}&page={str(j + 1)}"
data = requests.get(url).text
pat1_content_url = '<div class="docsum-wrap">.*?<.*?href="(.*?)".*?</a>'
content_url = re.compile(pat1_content_url, re.S).findall(data)
hd = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3748.400 QQBrowser/10.5.3863.400'
}
for i in range(0, len(content_url)):
if downloaded_count >= num:
break
curl = "https://pubmed.ncbi.nlm.nih.gov" + content_url[i]
try:
cdata = requests.get(curl, headers=hd).text
# 提取PMID
pmid_match = re.search(r'\/(\d+)\/*$', content_url[i])
if pmid_match:
pmid = pmid_match.group(1)
else:
continue # 如果没有找到PMID, 跳过这篇文章
pat3_content = '<div class="abstract-content selected".*?>(.*?)</div>'
content_html = re.compile(pat3_content, re.S).findall(cdata)[0]
# 使用BeautifulSoup解析HTML,并获取纯文本内容
soup = BeautifulSoup(content_html, 'html.parser')
content_text = soup.get_text(strip=True)
# 使用PMID作为文件名
file_name = f"{pmid}.txt"
file_path = os.path.join(local_folder, file_name)
# 写入摘要内容到文件
with open(file_path, "w", encoding="utf-8") as file:
file.write(content_text)
downloaded_count += 1 # 成功下载后,计数器增加
except Exception as err:
print(f"出现相关错误: {err}")
continue # 错误时继绌尝试下一篇文章
print(f"爬取了 {num} 文章数, 正确下载了 {downloaded_count} 文章数,爬取工作完成.")
python

三、使用方法
将上述代码保存为xxx.py格式,放入编译器中即可编译。
采用该方法时,请按照提示信息依次进行操作:首先输入所需爬取文章的关键字、文件存储位置以及预期的爬取数量;随后界面上方将依次显示匹配到的相关文献条目;该界面提供了一个搜索框供用户查找相关文献,并将搜索结果以表格形式展示。


在.txt文件中,是无html格式的纯文本文件。参考如下:

四、具体分析
1. 输入信息
key = input("请输入你想查找的信息:")
local_folder = input("请输入你想存储的文件夹位置:")
python
用户需要输入要查找的关键词和存储文件夹的位置。
2. 创建文件夹
if not os.path.exists(local_folder):
os.makedirs(local_folder)
python
如果文件夹不存在,则创建该文件夹。
3. 获取搜索结果总数
turl = "https://pubmed.ncbi.nlm.nih.gov/"
tdata = requests.get(turl, params={"term": key}).text
pat_alldocu = '<span class="value">(.*?)</span>'
alldocu = re.compile(pat_alldocu, re.S).findall(tdata)
python
发起请求至PubMed主页,并根据用户的关键词进行搜索以统计并返回总文献数量
4. 输入希望获取的文章数
num = int(input("请输入大致想获取的文章数目(总数为" + str(alldocu[0]) + "):"))
python
输入想要的页数
5. 逐页抓取文章信息
for j in range(0, (num - 1) // 10 + 1):
url = f"https://pubmed.ncbi.nlm.nih.gov/?term={key}&page={str(j + 1)}"
data = requests.get(url).text
pat1_content_url = '<div class="docsum-wrap">.*?<.*?href="(.*?)".*?</a>'
content_url = re.compile(pat1_content_url, re.S).findall(data)
python
根据每页的内容抓取文献摘要的URL。
6. 设置请求头
hd = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3748.400 QQBrowser/10.5.3863.400'
}
python
设置请求头以模拟浏览器请求,避免被服务器拒绝。
7. 下载并保存文章摘要
依次遍历当前页面获取的所有文章URL链接并生成完整的HTTP地址发送HTTP GET请求以获取详细HTML内容。在程序运行过程中若出现请求异常立即捕捉并记录错误信息。通过正则表达式匹配URL中的唯一标识符PMID若无法提取则跳过该条记录接着识别摘要所在的HTML段落利用BeautifulSoup解析工具将其转换为纯文本格式随后利用PMID作为文件名构造完整的下载路径最后将解析得到的摘要信息保存至本地txt文件
for i in range(0, len(content_url)):
if downloaded_count >= num:
break
curl = "https://pubmed.ncbi.nlm.nih.gov" + content_url[i]
try:
cdata = requests.get(curl, headers=hd).text
# 提取PMID
pmid_match = re.search(r'\/(\d+)\/*$', content_url[i])
if pmid_match:
pmid = pmid_match.group(1)
else:
continue # 如果没有找到PMID, 跳过这篇文章
pat3_content = '<div class="abstract-content selected".*?>(.*?)</div>'
content_html = re.compile(pat3_content, re.S).findall(cdata)[0]
# 使用BeautifulSoup解析HTML,并获取纯文本内容
soup = BeautifulSoup(content_html, 'html.parser')
content_text = soup.get_text(strip=True)
# 使用PMID作为文件名
file_name = f"{pmid}.txt"
file_path = os.path.join(local_folder, file_name)
# 写入摘要内容到文件
with open(file_path, "w", encoding="utf-8") as file:
file.write(content_text)
downloaded_count += 1 # 成功下载后,计数器增加
except Exception as err:
print(f"出现相关错误: {err}")
continue # 错误时继绌尝试下一篇文章
python

逐一查看每篇文章的详细页面内容;从每篇文章中获取摘要信息,并将其存储在本地文档中。请按照PMID编号为本地文档命名,并确保每个文档名称都是唯一的。
