Python

2013-07-01 12 views
7

का उपयोग कर PubMed से डेटा प्राप्त करना मेरे पास PubMed ID के साथ PubMed प्रविष्टियों की एक सूची है। मैं एक पायथन स्क्रिप्ट बनाना चाहता हूं या पायथन का उपयोग करना चाहता हूं जो एक पबमेड आईडी संख्या इनपुट के रूप में स्वीकार करता है और फिर पबमेड वेबसाइट से सार को प्राप्त करता है।Python

अब तक मैं पाइथन में एनसीबीआई ईटिविटीज और आयात पुस्तकालय में आया हूं लेकिन मुझे नहीं पता कि मुझे टेम्पलेट लिखने के बारे में कैसे जाना चाहिए।

किसी भी पॉइंटर्स की सराहना की जाएगी।

धन्यवाद,

उत्तर

3

वाह, मैं एक ऐसी ही परियोजना पर अपने आप को सिर्फ एक हफ्ते या तो पहले काम कर रहा था:

आपका कार्यप्रवाह की तरह कुछ करना चाहते हैं!

संपादित करें: मैंने हाल ही में BeautifulSoup का लाभ लेने के लिए कोड अपडेट किया है। मेरे पास इसके लिए अपना वर्चुअलएनवी है, लेकिन आप इसे पीआईपी से स्थापित कर सकते हैं।

असल में, मेरा प्रोग्राम एक पब्ड आईडी, एक डीओआई, या पबयुक्त आईडी और/या डीओआई की लाइनों की एक टेक्स्ट फ़ाइल लेता है, और लेख के बारे में जानकारी पकड़ता है। यह आसानी से सार प्राप्त करने के लिए अपनी जरूरतों के लिए बदलाव किया जा सकता है, लेकिन यहाँ मेरे कोड है:

import re 
import sys 
import traceback 
from bs4 import BeautifulSoup 
import requests 

class PubMedObject(object): 
    soup = None 
    url = None 

    # pmid is a PubMed ID 
    # url is the url of the PubMed web page 
    # search_term is the string used in the search box on the PubMed website 
    def __init__(self, pmid=None, url='', search_term=''): 
     if pmid: 
      pmid = pmid.strip() 
      url = "http://www.ncbi.nlm.nih.gov/pubmed/%s" % pmid 
     if search_term: 
      url = "http://www.ncbi.nlm.nih.gov/pubmed/?term=%s" % search_term 
     page = requests.get(url).text 
     self.soup = BeautifulSoup(page, "html.parser") 

     # set the url to be the fixed one with the PubMedID instead of the search_term 
     if search_term: 
      try: 
       url = "http://www.ncbi.nlm.nih.gov/pubmed/%s" % self.soup.find("dl",class_="rprtid").find("dd").text 
      except AttributeError as e: # NoneType has no find method 
       print("Error on search_term=%s" % search_term) 
     self.url = url 

    def get_title(self): 
     return self.soup.find(class_="abstract").find("h1").text 

    #auths is the string that has the list of authors to return 
    def get_authors(self): 
     result = [] 
     author_list = [a.text for a in self.soup.find(class_="auths").findAll("a")] 
     for author in author_list: 
      lname, remainder = author.rsplit(' ', 1) 
      #add periods after each letter in the first name 
      fname = ".".join(remainder) + "." 
      result.append(lname + ', ' + fname) 

     return ', '.join(result) 

    def get_citation(self): 
     return self.soup.find(class_="cit").text 

    def get_external_url(self): 
     url = None 
     doi_string = self.soup.find(text=re.compile("doi:")) 
     if doi_string: 
      doi = doi_string.split("doi:")[-1].strip().split(" ")[0][:-1] 
      if doi: 
       url = "http://dx.doi.org/%s" % doi 
     else: 
      doi_string = self.soup.find(class_="portlet") 
      if doi_string: 
       doi_string = doi_string.find("a")['href'] 
       if doi_string: 
        return doi_string 

     return url or self.url 

    def render(self): 
     template_text = '' 
     with open('template.html','r') as template_file: 
      template_text = template_file.read() 

     try: 
      template_text = template_text.replace("{{ external_url }}", self.get_external_url()) 
      template_text = template_text.replace("{{ citation }}", self.get_citation()) 
      template_text = template_text.replace("{{ title }}", self.get_title()) 
      template_text = template_text.replace("{{ authors }}", self.get_authors()) 
      template_text = template_text.replace("{{ error }}", '') 
     except AttributeError as e: 
      template_text = template_text.replace("{{ external_url }}", '') 
      template_text = template_text.replace("{{ citation }}", '') 
      template_text = template_text.replace("{{ title }}", '') 
      template_text = template_text.replace("{{ authors }}", '') 
      template_text = template_text.replace("{{ error }}", '<!-- Error -->') 

     return template_text.encode('utf8') 

def start_table(f): 
    f.write('\t\t\t\t\t\t\t\t\t<div class="resourcesTable">\n'); 
    f.write('\t\t\t\t\t\t\t\t\t\t<table border="0" cellspacing="0" cellpadding="0">\n'); 

def end_table(f): 
    f.write('\t\t\t\t\t\t\t\t\t\t</table>\n'); 
    f.write('\t\t\t\t\t\t\t\t\t</div>\n'); 

def start_accordion(f): 
    f.write('\t\t\t\t\t\t\t\t\t<div class="accordion">\n'); 

def end_accordion(f): 
    f.write('\t\t\t\t\t\t\t\t\t</div>\n'); 

def main(args): 
    try: 
     # program's main code here 
     print("Parsing pmids.txt...") 
     with open('result.html', 'w') as sum_file: 
      sum_file.write('<!--\n') 
     with open('pmids.txt','r') as pmid_file: 
     with open('result.html','a') as sum_file: 
     for pmid in pmid_file: 
      sum_file.write(pmid) 
     sum_file.write('\n-->\n') 
     with open('pmids.txt','r') as pmid_file: 
      h3 = False 
      h4 = False 
      table_mode = False 
      accordion_mode = False 
      with open('result.html', 'a') as sum_file: 
       for pmid in pmid_file: 
        if pmid[:4] == "####": 
         if h3 and not accordion_mode: 
          start_accordion(sum_file) 
          accordion_mode = True 
         sum_file.write('\t\t\t\t\t\t\t\t\t<h4><a href="#">%s</a></h4>\n' % pmid[4:].strip()) 
         h4 = True 
        elif pmid[:3] == "###": 
         if h4: 
          if table_mode: 
           end_table(sum_file) 
           table_mode = False 
          end_accordion(sum_file) 
          h4 = False 
          accordion_mode = False 
         elif h3: 
          end_table(sum_file) 
          table_mode = False 
         sum_file.write('\t\t\t\t\t\t\t\t<h3><a href="#">%s</a></h3>\n' % pmid[3:].strip()) 
         h3 = True       
        elif pmid.strip(): 
         if (h3 or h4) and not table_mode: 
          start_table(sum_file) 
          table_mode = True 
         if pmid[:4] == "http": 
          if pmid[:18] == "http://dx.doi.org/": 
           sum_file.write(PubMedObject(search_term=pmid[18:]).render()) 
          else: 
           print("url=%s" % pmid) 
           p = PubMedObject(url=pmid).render() 
           sum_file.write(p) 
           print(p) 
         elif pmid.isdigit(): 
          sum_file.write(PubMedObject(pmid).render()) 
         else: 
          sum_file.write(PubMedObject(search_term=pmid).render()) 
       if h3: 
        if h4: 
         end_table(sum_file) 
         end_accordion(sum_file) 
        else: 
         end_table(sum_file) 
      pmid_file.close() 
     print("Done!") 

    except BaseException as e: 
     print traceback.format_exc() 
     print "Error: %s %s" % (sys.exc_info()[0], e.args) 
     return 1 
    except: 
     # error handling code here 
     print "Error: %s" % sys.exc_info()[0] 
     return 1 # exit on error 
    else: 
     raw_input("Press enter to exit.") 
     return 0 # exit errorlessly 

if __name__ == '__main__': 
    sys.exit(main(sys.argv)) 

अब यह जानकारी इसे डाउनलोड के आधार पर एक HTML फ़ाइल देता है। यहां टेम्पलेट.txt:

<tr>{{ error }} 
    <td valign="top" class="resourcesICO"><a href="{{ external_url }}" target="_blank"><img src="/image/ico_sitelink.gif" width="24" height="24" /></a></td> 
    <td><a href="{{ external_url }}">{{ title }}</a><br /> 
    {{ authors }}<br /> 
    <em>{{ citation }}</em></td> 
</tr> 

जब आप इसे चलाते हैं, तो प्रोग्राम आपको डीओआई या पब्ड आईडी के लिए पूछेगा। यदि आप एक प्रदान नहीं करते हैं, तो यह pmids.txt को पढ़ेगा। जैसा कि आप फिट देखते हैं, कोड का उपयोग करने के लिए स्वतंत्र हो जाएं।

+0

आप Bobort धन्यवाद, मैं इतना है कि यह सिर्फ अमूर्त की जानकारी हो जाता है इस कोड में और सुधार करने के लिए जा रहा हूँ। इसके अलावा, मैं इसे एक और स्क्रिप्ट के साथ एकीकृत कर दूंगा जो पब्ड आईडी को संरचनात्मक शीर्षक और उद्धरण शीर्षक में मानचित्रित करता है। –

+0

मुझे डाउन वोट क्यों मिला? जवाब देने और छोड़ने के लिए कितना असहज! – Bobort

+0

हाय बॉबर्ट, मुझे लगता है कि किसी और ने जवाब दिया है। मैं यह तुम्हारे लिए ठीक कर दूंगा। –

1

Pubmed लेख फ़ॉर्म दिया गया है: http://www.ncbi.nlm.nih.gov/pubmed/?Id

आप आईडी पता है तो आप इसके बाद के संस्करण प्राप्त कर सके और आप लेख के लिए उपयोग होगा।

<div class="abstr"><h3>Abstract</h3><div class=""><p>α-latrotoxin and snake presynaptic phospholipases A2 neurotoxins target the presynaptic membrane of axon terminals of the neuromuscular junction....</p></div></div> 

तब आप उस को निकालने के लिए एक उपकरण की आवश्यकता होगी: सार की तरह एक संरचना के भीतर निहित है। मैं इसका उपयोग करने का सुझाव दूंगा: http://www.crummy.com/software/BeautifulSoup/bs4/doc/

आपको अभी भी एचटीएमएल लाने के लिए एक उपकरण की आवश्यकता होगी। इसके लिए मैं phantom.js या कभी भी लोकप्रिय अनुरोध मॉड्यूल का उपयोग करूंगा।

pubmed_ids [1,2,3] 
abstracts = [] 

for id in pubmed_ids: 
html_for_id = requests.get('http://www.ncbi.nlm.nih.gov/pubmed/{0}'.format(id)) 
soup = BeautifulSoup(html_for_id) 
abstract = soup.find('selector for abstract') 
abstracts.append(abstract) 
19

Biopython का मॉड्यूल Entrez नामक मॉड्यूल का उपयोग करके, आप सभी अन्य मेटाडेटा के साथ सार आसानी से प्राप्त कर सकते हैं। यहाँ

from Bio.Entrez import efetch 

def print_abstract(pmid): 
    handle = efetch(db='pubmed', id=pmid, retmode='text', rettype='abstract') 
    print handle.read() 

और एक समारोह है कि XML लाने और सिर्फ सार वापस आ जाएगी है:: इस सार प्रिंट होगा

from Bio.Entrez import efetch, read 

def fetch_abstract(pmid): 
    handle = efetch(db='pubmed', id=pmid, retmode='xml') 
    xml_data = read(handle)[0] 
    try: 
     article = xml_data['MedlineCitation']['Article'] 
     abstract = article['Abstract']['AbstractText'][0] 
     return abstract 
    except IndexError: 
     return None 

पी.एस. मुझे वास्तव में एक वास्तविक कार्य में इस तरह की चीजें करने की आवश्यकता थी, इसलिए मैंने कोड को कक्षा - see this gist में व्यवस्थित किया।

+1

यह एक बहुत अच्छा मॉड्यूल की तरह दिखता है। मुझे नहीं पता था कि यह अस्तित्व में था। हालांकि, मेरे कोड के बारे में एक अच्छी बात यह है कि यह डीओआई मान प्राप्त करता है ताकि यूआरएल पुनर्प्राप्त संभव हो सके। मुझे लगता है कि एंटरेज मॉड्यूल में ऐसी सुविधाएं मौजूद हो सकती हैं, लेकिन मैंने इसमें गहराई से नहीं देखा है। – Bobort

+0

मुझे यकीन नहीं है कि यूआरएल द्वारा आपका क्या मतलब है ... biopython दृश्यों के पीछे सभी पूछताछ करता है, इसलिए आपको किसी भी यूआरएल के साथ खेलने की जरूरत नहीं है। – Karol

+0

यह ठीक है। मेरा आवेदन 'http://dx.doi.org/' बनाता है ताकि मैं इसे किसी वेबसाइट में उपयोग कर सकूं। पबमेड सामान पर जाने के बजाय, मैं सीधे लेख पर जाना चाहता हूं। सबसे सामान्य तरीका मुझे अभी पता है कि प्रोग्रामर अनुकूल है डीओआई स्कीमा का उपयोग करना है। – Bobort

0

लगता है 'पैटर्न' मॉड्यूल आसानी से कर सकते हैं:

from pattern import web 
 
import requests 
 

 
id = 27523945 
 
url = "http://www.ncbi.nlm.nih.gov/pubmed/{0}".format(id) 
 
page = requests.get(url).text.encode('ascii', 'ignore') 
 
dom = web.Element(page) 
 
print(dom.by_tag("abstracttext")[0].content)