NCBI(pubmed)里医学主题词(MeSH)完整词库获取

3 篇文章 0 订阅
1 篇文章 0 订阅

NCBI(pubmed)里医学主题词(MeSH)完整词库获取

转载提示:原创文章,转载前请联系我!!

前言

本文主要介绍MeSH词库的获取方法,有两种方式:1.官网的下载页面,2.对网页进行爬取。本文主要介绍第二种方法。MeSH词库官网:https://www.ncbi.nlm.nih.gov/mesh

一、MeSH词库是什么?

医学主题词(MeSH)是一种用于生物医学信息的索引和分类的层次结构术语。它用于为PubMed和其他NLM数据库建立索引。

二、获取MeSH词库的方式

根据项目需要选择适合项目的获取方式!!!

1.从官网的下载页面里下载

下载页面:https://www.nlm.nih.gov/databases/download/mesh.html

2.使用python和requests对网页进行爬取

在官网下载页面下载的数据清洗也比较费时费力,而且此网站没有反爬,能轻松获取到我们想要的数据,所以爬取也是一种较好的方式。

三、使用python和requests对网页进行爬取

1.项目需求

  • 提供一个完整的MeSH词库,供项目使用。需要上下级关系,能够根据需要搜索的词找到它本身的同义词和它的所有下级节点以及它的所有下级节点的同义词

2.网站特点

  • 以下图为例,搜索Dental Care,网址:https://www.ncbi.nlm.nih.gov/mesh/68003729

  • 在这里插入图片描述

  • 上图可以看出:词在词库的位置有两个,以逗号分隔,并且下面树状结构也是两个。只要我们把每一个和它在词库里的位置都获取下来,就能得到一个完整得词库。使用时只需找出词在词库的位置,根据词在词库的位置就能找到它所有的下级词。

  • 例:上图搜索的词是Dental Care,词在词库的位置是E06.170N02.421.240.190,它的下级词的位置必定包含上面两个,格式是E06.170.xxx N02.421.240.190.xxx,所以找出所有包含上面两个位置的词就是Dental Care的下级词。例如用鼠标点击下级词:Dental Care for Aged,它在词库里的位置是E06.170.100N02.421.240.190.210,可见有了Dental Care在词库的位置就能查出它所有的下级词。

  • 在这里插入图片描述

3.爬取目标

目标:获取网页上每一个以及它的Entry TermsTree Number(s)
实际爬虫的时候:为了将整个词库完整得获取下来,就需要将搜索词的下级词href网址也都获取下来,然后遍历。
下图示例:若看不清可保存图片放大!!!!
在这里插入图片描述
官网:https://www.ncbi.nlm.nih.gov
例:下级词的href="/mesh/68016321",它的url就是官网+href。
url:https://www.ncbi.nlm.nih.gov/mesh/68016321

4.存储格式

  • 我是用txt存储的,也可选择其他格式!!
  • 分割1.搜索的词2.词在词库里的位置,分割1.搜索的词3.词的同义词
  • 在这里插入图片描述

5.项目文件

在这里插入图片描述

6.具体代码

# -*- coding: utf-8 -*-
import requests
import time
from lxml import etree
import pandas as pd

#  作者:csdn.美味大香蕉
#  日期:2020-11-10

# 卍分割1.搜索的词与2.词在词库里的位置,※分割1.搜索的词与3.词的同义词

#写入txt
def writeTxt(text):
    file = open('./data.txt', 'a', encoding='utf-8')
    file.write(text + "\n")
    file.close()

#爬取网页
def Request(url):
    response = requests.get(url,timeout=10)
    time.sleep(2)
    # print(response)
    response.encoding = 'utf-8'
    textData = response.text
    resHtml = etree.HTML(textData.encode('utf-8'))
    return resHtml
    
#主程序
def crawl():
    #官网
    baseUrl="https://www.ncbi.nlm.nih.gov"
    #起始词All MeSH Categories
    queueHref=["/mesh/1000048"]
    endHref=[]
    #统计写入txt的数据量
    num=0
    #标记错误链接的重试次数
    tag=0
    #开始时间
    startTime=time.time()
    while  queueHref !=[]:
        try:
            headHref=queueHref[0]
            print(headHref)
            #拼接url
            url = baseUrl + headHref
            #获取网页
            html=Request(url)
            #从网页上获取href
            xpath = '//*[@id="maincontent"]/div/div[5]/div//@href'
            hrefData = html.xpath(xpath)
            if len(hrefData)>0:
                for h in hrefData:
                    if h not in endHref and h not in queueHref and h[:6] =="/mesh/":
                        queueHref.append(h)
            # 从网页上获取 词
            nameXpath = '//*[@id="maincontent"]/div/div[5]/div/h1/text()'
            nameData=html.xpath(nameXpath)
            # 从网页上获取 entryTerms
            entryTermsXpath = '//*[@id="maincontent"]/div/div[5]/div/ul[1]/*/text()'
            entryTermsData = html.xpath(entryTermsXpath)
            entryTerms=""
            if len(entryTermsData)>1:
                entryTermsData3=[]
                for e in range(len(entryTermsData)):
                    entryTermsXpath2 = '//*[@id="maincontent"]/div/div[5]/div/ul[1]/li['+str(e+1)+']//text()'
                    entryTermsData2 = html.xpath(entryTermsXpath2)
                    if len(entryTermsData2)>0:
                        entryTermsData3.append("".join(entryTermsData2))
                entryTerms="※".join(entryTermsData3)
            elif len(entryTermsData)==1:
                if entryTermsData[0] !="All MeSH Categories":
                    entryTerms = entryTermsData[0]
            # 从网页上获取 Tree Number(s)
            idXpath = '//*[@id="maincontent"]/div/div[5]/div/p/text()'
            idData=html.xpath(idXpath)
            if len(idData)>0:
                for i2 in idData:
                    if "Tree Number(s): " in i2:
                        ids=i2.replace("Tree Number(s): ","")
                        ids=ids.split(", ")
                        #将数据写入txt
                        for id in ids:
                            writeTxt(id + "卍" + nameData[0]+"※"+entryTerms)
                            num+=1
                            print("已写入第"+str(num)+"个数据。")
            #更新queueHref和endHref
            queueHref.remove(headHref)
            endHref.append(headHref)
            tag = 0
        except:
            #若重试次数等于10次,就将错误的Href保存至errorLog.txt
            if tag==10:
                queueHref.remove(headHref)
                endHref.append(headHref)
                file = open('./errorLog.txt', 'a', encoding='utf-8')
                file.write(headHref + "\n")
                file.close()
                tag = 0
                print("*" * 30)
                print("数据错误,已保存至txt!!!!!!")
                print("*" * 30)
            tag+=1
            #保存queueHref和endHref
            pd.to_pickle(queueHref, "./queueHref.pkl")
            pd.to_pickle(endHref, "./endHref.pkl")
            #读取queueHref和endHref
            endHref = pd.read_pickle("./endHref.pkl")
            queueHref = pd.read_pickle("./queueHref.pkl")
            #发生错误的时间
            zTime=time.time()
            print("*" * 30)
            print("已用时:"+str(zTime-startTime)+"秒!!")
            print("发生错误,程序10秒后自动开始运行,!!!!!!")
            print("*" * 30)
            time.sleep(10)

    #程序运行完的时间
    endTime=time.time()
    print("※" * 30)
    print("总用时:"+str(endTime-startTime)+"秒!!")
    print("爬取完成!!")
    print("※" * 30)

if __name__=="__main__":
    crawl()

7.项目成果

在这里插入图片描述

总结

上面项目和代码只是本人演示交流所用,请各位帅哥美女根据实际项目需要再做修改。

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值