1

FASTAGI 番号のファイルがあり、ncbi から配列を取得したいと考えています。

from Bio import Entrez
import time
Entrez.email ="eigtw59tyjrt403@gmail.com"
f = open("C:\\bioinformatics\\gilist.txt")
for line in iter(f):
    handle = Entrez.efetch(db="nucleotide", id=line, retmode="xml")
    records = Entrez.read(handle)
    print ">GI "+line.rstrip()+" "+records[0]["GBSeq_primary-accession"]+" "+records[0]["GBSeq_definition"]+"\n"+records[0]["GBSeq_sequence"]
    time.sleep(1) # to make sure not many requests go per second to ncbi
f.close()

このスクリプトは正常に実行されますが、いくつかのシーケンスの後、突然このエラー メッセージが表示されます。

Traceback (most recent call last):
  File "C:/Users/Ankur/PycharmProjects/ncbiseq/getncbiSeq.py", line 7, in <module>
    handle = Entrez.efetch(db="nucleotide", id=line, retmode="xml")
  File "C:\Python27\lib\site-packages\Bio\Entrez\__init__.py", line 139, in efetch
    return _open(cgi, variables)
  File "C:\Python27\lib\site-packages\Bio\Entrez\__init__.py", line 455, in _open
    raise exception
urllib2.HTTPError: HTTP Error 500: Internal Server Error

もちろん使用できますhttp://www.ncbi.nlm.nih.gov/sites/batchentrezが、パイプラインを作成しようとしており、自動化が必要です。

ncbiが「私を追い出す」のを防ぐにはどうすればよいですか

4

3 に答える 3

0

efetch と呼ばれる回避策があります。リストを 200 個のバッチに分割し (直感的にはこれで十分なバッチ サイズです)、efetchを使用してこれらすべての ID を一度に送信できます。

まず、これは 200 個のクエリを個別に送信するよりもはるかに高速です。第 2 に、クエリあたりの処理時間は 0.33 秒を超えますが、それほど長くはないため、「1 秒あたり 3 クエリ」のルールにも効果的に準拠しています。

ただし、「悪いリンゴ」をキャッチするメカニズムが必要です。NCBI は、200 個の ID のうち 1 個が正しくない場合でも、0 の結果を返します。つまり、NCBI は、200 個の ID がすべて有効である場合にのみ結果を返します。

悪いリンゴの場合、200 個の ID を 1 つずつ繰り返し処理し、悪いリンゴを無視します。この「悪いリンゴの場合」のシナリオは、悪いリンゴの場合に備えて、バッチを大きくしすぎないことも示しています。それが大きい場合、まず、悪いリンゴができる可能性が高くなります。つまり、全体を反復する必要がより多くなります。第 2 に、バッチが大きくなればなるほど、反復する必要がある個々の項目が多くなります。

次のコードを使用して CAZy タンパク質をダウンロードすると、うまく機能します。

import urllib2


prefix = "http://www.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=protein&rettype=fasta&id="
id_per_request = 200


def getSeq (id_list):
    url = prefix + id_list[:len(id_list)-1]

    temp_content = ""
    try:
        temp_content += urllib2.urlopen(url).read()

### if there is a bad apple, try one by one
    except:
        for id in id_list[:len(id_list)-1].split(","):
            url = prefix + id
    #print url
            try:
                temp_content += urllib2.urlopen(url).read()
            except:
            #print id
                pass
    return temp_content


content = ""
counter = 0
id_list = ""

#define your accession numbers first, here it is just an example!!

accs = ["ADL19140.1","ABW01768.1","CCQ33656.1"]
for acc in accs:

    id_list += acc + ","
    counter += 1

    if counter == id_per_request:
        counter = 0
        content += getSeq(id_list)
        id_list = ""

if id_list != "":
    content += getSeq(id_list)
    id_list = ""


print content
于 2014-06-20T21:49:50.297 に答える
0

私は ncbi API に精通していませんが、何らかのレート制限ルールに違反しているので ( "sleep(1)" を使用しても)、以前のリクエストは機能しますが、いくつかのリクエストの後、サーバーはあなたが頻繁にそれを打っていて、あなたをブロックしていること。コードにエラー処理がないため、これは問題です。

データ フェッチを try/except ブロックでラップして、スクリプトの待機時間を長くし、問題が発生した場合は再試行することをお勧めします。他のすべてが失敗した場合は、エラーの原因となった ID をファイルに書き込んで続行します (ID が何らかの原因である場合、Entrez ライブラリが不正な URL を生成する可能性があります)。

コードを次のように変更してみてください (未テスト):

from urllib2 import HTTPError
from Bio import Entrez
import time

def get_record(_id):
    handle = Entrez.efetch(db="nucleotide", id=_id, retmode="xml")
    records = Entrez.read(handle)
    print ">GI "+line.rstrip()+" "+records[0]["GBSeq_primary-accession"]+" "+records[0]["GBSeq_definition"]+"\n"+records[0]["GBSeq_sequence"]
    time.sleep(1) # to make sure not many requests go per second to ncbi

Entrez.email ="eigtw59tyjrt403@gmail.com"
f = open("C:\\bioinformatics\\gilist.txt")
for id in iter(f):
    try:
        get_record(id)
    except HTTPError:
        print "Error fetching", id
        time.sleep(5) # we have angered the API! Try waiting longer?
        try:
            get_record(id)
        except:
            with open('error_records.bad','a') as f:
                f.write(str(id)+'\n')
            continue # 
f.close()
于 2013-02-12T07:33:51.640 に答える