pubmed api
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
artikel
code
date
datum
format
history
http
jeweilige struktur
jeweilige url
krieg
methanol
nerven
qual
schema
schleife
term
type
url
zugreifen
zweites problem
-
Hallo,
ich muss gerade über die PubMed API (PubMed ist eine Datenbank über medizinische Artikel) versuchen ein paar Artikel zu exportieren. Nach ein bisschen rumgesuche, habe ich http://www.ncbi.nlm.nih.gov/books/NBK25501/ gefunden. An sich eine gute, kurze Erklärung, wie die PubNet bzw. Entrez API funktioniert. Nun kriege ich aber eine ganz wichtige essentielle Sachen nicht gebacken, vllt. kann mir da einer von euch weiterhelfen:
Ich möchte die Artikel mit den IDs 1-100 aus PubNet über die API ansprechen, so dass ich sie nachher mit einem eigenen PHP Script auf meinem Server weiterverarbeiten kann. Wie mache ich das? Artikel "downloaden" geschieht über die fetch Datei von deren API. Also ungefähr so:
http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=1
Das gibt mir die Ausgabe:
Pubmed-entry ::= { pmid 1, medent { em std { year 1976, month 1, day 16 }, cit { title { name "Formate assay in body fluids: application in methanol poisoning." }, authors { names ml { "Makar AB", "McMartin KE", "Palese M", "Tephly TR" } }, from journal { title { iso-jta "Biochem Med", ml-jta "Biochem Med", issn "0006-2944", name "Biochemical medicine" }, imp { date std { year 1975, month 6 }, volume "13", issue "2", pages "117-126", language "eng", pubstatus ppublish, history { { pubstatus pubmed, date std { year 1975, month 6, day 1 } }, { pubstatus medline, date std { year 1975, month 6, day 1, hour 0, minute 1 } }, { pubstatus other, date std { year 1975, month 6, day 1, hour 0, minute 0 } } } } }, ids { pubmed 1 } }, mesh { { term "Aldehyde Oxidoreductases", qual { { subh "metabolism" } } }, { term "Animals" }, { term "Body Fluids", qual { { mp TRUE, subh "analysis" } } }, { term "Carbon Dioxide", qual { { subh "blood" } } }, { term "Formates", qual { { subh "blood" }, { mp TRUE, subh "poisoning" } } }, { term "Haplorhini" }, { term "Humans" }, { term "Hydrogen-Ion Concentration" }, { term "Kinetics" }, { term "Methanol", qual { { subh "blood" } } }, { term "Methods" }, { term "Pseudomonas", qual { { subh "enzymology" } } } }, substance { { type nameonly, name "Formates" }, { type cas, cit "124-38-9", name "Carbon Dioxide" }, { type cas, cit "67-56-1", name "Methanol" }, { type ec, cit "1.2.-", name "Aldehyde Oxidoreductases" } }, pmid 1, pub-type { "Journal Article", "Research Support, U.S. Gov't, P.H.S." }, status medline } }
Dort ist alle relevante Information über den PubMed Artikel mit der ID 1 enthalten. Ich möchte aber die Artikel 1 bis 100 erhalten. Ich habe schon Angaben wie id=1:100 etc. durchprobiert. WIe kriege ich das hin? So wie ich das in der Erklärung gesehen habe, funktioniert nur eine Aufzählung der einzelnen Artikel, aber ich habe eher wenig Interesse daran sämtliche Artikel von 1 bis 100 aufzuzählen. Ja, ich weiß ich kann mir ein PHP Script schreiben, dass mit einer for Schleife 100 mal die jeweilige URL aufruft, aber das muss doch eleganter gehen.
Zweites Problem: Wenn ich nun die jeweilige Ausgabe habe, wie verarbeite ich die mit PHP möglichst effizient? Soll ich da einfach file_get_content($url); benutzen und dann die jeweilige Struktur mit explodes() zerlegen, oder geht das eleganter?
Danke.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
midwar schrieb:
Dort ist alle relevante Information über den PubMed Artikel mit der ID 1 enthalten. Ich möchte aber die Artikel 1 bis 100 erhalten. Ich habe schon Angaben wie id=1:100 etc. durchprobiert. WIe kriege ich das hin? So wie ich das in der Erklärung gesehen habe, funktioniert nur eine Aufzählung der einzelnen Artikel, aber ich habe eher wenig Interesse daran sämtliche Artikel von 1 bis 100 aufzuzählen. Ja, ich weiß ich kann mir ein PHP Script schreiben, dass mit einer for Schleife 100 mal die jeweilige URL aufruft, aber das muss doch eleganter gehen.
Normalerweise, muss man nicht die Informationen von allen Artikeln auf einmal abrufen. Du musst es dir so vorstellen, dass du die Daten nicht von dort übernimmst, sondern immer von dort aufrufst. Beispiel: Du hast eine Liste mit den Einträgen und wenn man auf diesen Klickt, wird über die API genau von diesem Artikel alle weiteren Infos ausgelesen. Natürlich kannst du die Infos aber auch in einer Schleife laden.
Zweites Problem: Wenn ich nun die jeweilige Ausgabe habe, wie verarbeite ich die mit PHP möglichst effizient? Soll ich da einfach file_get_content($url); benutzen und dann die jeweilige Struktur mit explodes() zerlegen, oder geht das eleganter?
Natürlich nicht! Die Daten liegen in JSON vor, dazu brauchst du nur einen JSON-Parser um einfach auf die enthaltenen Informationen zugreifen zu können. Dir einen eigenen (zB mit explodes) zu schreiben, würde dir nur Zeit und Nerven kosten ;) -
trueweb schrieb:Natürlich nicht! Die Daten liegen in JSON vor, dazu brauchst du nur einen JSON-Parser um einfach auf die enthaltenen Informationen zugreifen zu können. Dir einen eigenen (zB mit explodes) zu schreiben, würde dir nur Zeit und Nerven kosten ;)
Hm mit JSON kenne ich mich nicht so gut aus. Ich hab stattdessen mal bei der entrez API angegeben, dass ich den Text in XML ausgegeben haben möchte. Dann kann ich ja mit simplexml draufzugreifen.
Also ungefähr so:
<?php error_reporting(E_ALL); $xml_file = simplexml_load_file("http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=1&retmode=xml"); $year = $xml_file->PubmedArticle->PubmedData->History->PubMedPubDate->Year; $month = $xml_file->PubmedArticle->PubmedData->History->PubMedPubDate->Month; $day = $xml_file->PubmedArticle->PubmedData->History->PubMedPubDate->Day; ?>
Von diesem XML Baum:
<?xml version="1.0" ?> <!DOCTYPE PubmedArticleSet (View Source for full doctype...)> - <PubmedArticleSet> - <PubmedArticle> - <MedlineCitation Owner="NLM" Status="MEDLINE"> <PMID Version="1">1</PMID> - <DateCreated> <Year>1976</Year> <Month>01</Month> <Day>16</Day> </DateCreated> - <DateCompleted> <Year>1976</Year> <Month>01</Month> <Day>16</Day> </DateCompleted> - <DateRevised> <Year>2009</Year> <Month>11</Month> <Day>11</Day> </DateRevised> - <Article PubModel="Print"> - <Journal> <ISSN IssnType="Print">0006-2944</ISSN> - <JournalIssue CitedMedium="Print"> <Volume>13</Volume> <Issue>2</Issue> - <PubDate> <Year>1975</Year> <Month>Jun</Month> </PubDate> </JournalIssue> <Title>Biochemical medicine</Title> <ISOAbbreviation>Biochem Med</ISOAbbreviation> </Journal> <ArticleTitle>Formate assay in body fluids: application in methanol poisoning.</ArticleTitle> - <Pagination> <MedlinePgn>117-26</MedlinePgn> </Pagination> - <AuthorList CompleteYN="Y" Type="authors"> - <Author ValidYN="Y"> <LastName>Makar</LastName> <ForeName>A B</ForeName> <Initials>AB</Initials> </Author> - <Author ValidYN="Y"> <LastName>McMartin</LastName> <ForeName>K E</ForeName> <Initials>KE</Initials> </Author> - <Author ValidYN="Y"> <LastName>Palese</LastName> <ForeName>M</ForeName> <Initials>M</Initials> </Author> - <Author ValidYN="Y"> <LastName>Tephly</LastName> <ForeName>T R</ForeName> <Initials>TR</Initials> </Author> </AuthorList> <Language>eng</Language> - <PublicationTypeList> <PublicationType>Journal Article</PublicationType> <PublicationType>Research Support, U.S. Gov't, P.H.S.</PublicationType> </PublicationTypeList> </Article> -- GELÖSCHT --- <Day>1</Day> <Hour>0</Hour> <Minute>1</Minute> </PubMedPubDate> - <PubMedPubDate PubStatus="entrez"> <Year>1975</Year> <Month>6</Month> <Day>1</Day> <Hour>0</Hour> <Minute>0</Minute> </PubMedPubDate> </History> <PublicationStatus>ppublish</PublicationStatus> - <ArticleIdList> <ArticleId IdType="pubmed">1</ArticleId> </ArticleIdList> </PubmedData> </PubmedArticle> </PubmedArticleSet>
Ich habe mich jetzt allerdings in Google totgesucht und kann nirgendwo finden, wo das hier ausgegebene XML Schema erklärt wird. Manche dieser Einträge erschließen sich mir nicht. Und ich muss auch, wenn du trueweb eben gesagt hast man braucht nciht alle Daten - ich brauche sie schon. Und ich muss diese halt weiterverarbeiten (ungefähr so wie ich es oben angefangen hatte). Aber wo finde ich eine vernünftige Definition des XML Schemas, damit ich vernünftig damit weiterarbeiten kann?
(Ich musste mitten im XML Schema was rausschnibbeln, weil Lima mich sonst nicht posten lassen wollte - ist daher nicht das komplette).
EDIT:
So ich hab angefangen mir einen eigenen Mini-Parser zu basteln:
<?php $xml_file = simplexml_load_file("http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=1&retmode=xml"); class Parser { public $Variables = array(); public function parse($xml,$i) { if($xml->count() > 0) { $i += 1; foreach($xml->children() as $node) { echo "NODENAME: " . $node->getName() . " - EBENE: $i<br>"; $nodename = $node->getName(); /*echo gettype($node); if(gettype($node) != object) { $this->Variables["$nodename"] = $node; } */ $this->parse($node,$i); } } } } $PUBMED_PARSER = new Parser(); $PUBMED_PARSER->parse($xml_file,0); var_dump($PUBMED_PARSER->Variables); ?>
Kurz zur Erklärung: ich gehe jede $node des XML Baums durch und schaue, ob sie weitere childs hat. Wenn ja, starte ich die die Funktion mit der neuen $node einfach neu. Wenn nun ein $node Werte gespeichert hat, wie "Year:1976", dann sollen die auch bitte an $PUBMED_PARSER->Variables hinzugefügt werden. Ich möchte also, dass am Ende alle Variablen und Werte, die ich aus dem XML auslesen kann in meinem Variables Array vorhanden sind.
Ich kann nicht einfach nur bei jedem $node Durchlauf $this->Variables["$nodename"] = $node; schreiben, weil manche $nodes auch einfach nichts beinhalten. Wie aber kann ich das überprüfen? Mit gettype() erhalte ich nur immer object und kann daher nicht über if(gettype($node) != object) gehen. Es muss also irgendwie anders gehen. Wie kann ich überprüfen, ob das aktuelle $node Text oder Zahlen gespeichert hat? echo $node gibt mir einfach immer den Wert aus, wenn einer vorhanden ist - hierüber kann ich also auch nicht unterscheiden.
Irgendwie sind die simpleXML Erklärungen im Web dazu überhaupt nicht gut, oder habe ich einfach zu eilig gegoogelt und was übersehen? Wer kennt da noch gute Links?
Danke!
Beitrag zuletzt geändert: 19.6.2012 15:33:15 von midwar -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage