
在进行网页数据抓取时,开发者常会遇到一个普遍问题:尽管通过requests库成功获取了网页的html内容,但使用beautifulsoup等解析库却无法找到页面上明显存在的元素。这通常是因为目标网站采用了javascript动态加载内容的技术。这意味着当您使用requests.get()请求页面时,服务器返回的html文档可能只包含一个基础框架,而实际的数据(例如uniprot的条目id列表)是在浏览器端通过javascript执行异步请求(ajax/fetch)后才填充到页面中的。
对于UniProt网站,当我们尝试使用以下代码来提取条目ID时:
import requests
from bs4 import BeautifulSoup
url = "https://www.uniprot.org/uniprotkb?query=wound+healing"
res = requests.get(url)
res.raise_for_status()
soup = BeautifulSoup(res.text, "html.parser")
links = soup.find_all("a", class_="BqBnJ")
# 此时 links 将是一个空列表,因为包含 ID 的内容尚未加载尽管print(res.text)能够显示HTML文本,但其中并不包含那些动态加载的<a class="BqBnJ" ...>标签。这是因为requests库只获取了服务器的原始响应,并未执行任何JavaScript代码。因此,BeautifulSoup在解析这个初始HTML时,自然无法找到动态生成的内容。
面对动态加载内容,最稳健且推荐的解决方案是使用网站提供的官方API(Application Programming Interface)。API是网站为了方便开发者程序化访问其数据而设计的一套接口。UniProt提供了一个功能强大的REST API,允许用户直接查询和获取蛋白质数据,而无需进行网页解析。
UniProt REST API的/uniprotkb/search端点允许我们根据查询条件搜索蛋白质条目,并指定需要返回的字段。这比模拟浏览器行为抓取网页要高效和稳定得多。
以下代码演示了如何使用UniProt REST API来搜索“wound healing”相关的条目,并提取它们的“primaryAccession”(即UniProt ID):
import requests
import json # 用于处理JSON响应
api_url = "https://rest.uniprot.org/uniprotkb/search"
# 定义查询参数
params = {
"fields": "accession,id,protein_name,gene_names,organism_name,length", # 指定需要返回的字段
"query": "(wound healing)", # 查询字符串
"size": 5 # 限制返回结果的数量,便于演示
}
try:
# 发送GET请求到API
response = requests.get(api_url, params=params)
response.raise_for_status() # 检查请求是否成功(状态码200)
# 解析JSON响应
data = response.json()
print("--- 提取的UniProt条目ID ---")
if "results" in data and data["results"]:
for r in data["results"]:
print(r["primaryAccession"])
else:
print("未找到匹配的条目。")
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
except json.JSONDecodeError:
print("无法解析API响应为JSON。")
代码解析:
示例输出:
--- 提取的UniProt条目ID --- O00622 Q15746 Q04912 P08581 Q61176
UniProt API还提供了/uniprotkb/stream端点,它更适合于批量下载大量数据,类似于网站上的“下载”按钮功能。通过这个端点,您可以指定下载格式(如JSON、FASTA、TXT等)和是否压缩。
以下代码展示了如何使用/stream端点来获取“wound healing”查询的所有结果,并以JSON格式返回:
import requests
import json
api_url_stream = "https://rest.uniprot.org/uniprotkb/stream"
# 定义流式下载参数
params_stream = {
"compressed": "false", # 不压缩
"download": "true", # 模拟下载行为
"format": "json", # 指定下载格式为JSON
"query": "(wound healing)",
"size": 5 # 限制返回结果的数量,便于演示
}
try:
# 发送GET请求到API
response_stream = requests.get(api_url_stream, params=params_stream)
response_stream.raise_for_status()
# 解析JSON响应
data_stream = response_stream.json()
print("\n--- 通过流式API提取的UniProt条目ID ---")
if "results" in data_stream and data_stream["results"]:
for r in data_stream["results"]:
print(r["primaryAccession"])
else:
print("未通过流式API找到匹配的条目。")
except requests.exceptions.RequestException as e:
print(f"流式请求失败: {e}")
except json.JSONDecodeError:
print("无法解析流式API响应为JSON。")
代码解析:
通过本教程,我们理解了传统网页抓取方法在面对JavaScript动态加载内容时的局限性,并掌握了利用UniProt REST API高效、稳定地获取蛋白质条目ID的方法。这种方法不仅解决了动态内容的问题,还提供了更结构化、更易于处理的数据。在未来的数据获取任务中,识别动态内容并优先考虑使用官方API将是您提升效率和代码鲁棒性的关键。
以上就是高效获取UniProt数据库条目ID:应对动态加载与API应用实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号