2012-07-17 4 views
6

Diese einfache Python 3 Skript:Wie behebe ich einen ValueError: Lese von Closed File Exception?

import urllib.request 

host = "scholar.google.com" 
link = "/scholar.bib?q=info:K7uZdMSvdQ0J:scholar.google.com/&output=citation&hl=en&as_sdt=1,14&ct=citation&cd=0" 
url = "http://" + host + link 
filename = "cite0.bib" 
print(url) 
urllib.request.urlretrieve(url, filename) 

hebt diese Ausnahme:

Traceback (most recent call last): 
    File "C:\Users\ricardo\Desktop\Google-Scholar\BibTex\test2.py", line 8, in <module> 
    urllib.request.urlretrieve(url, filename) 
    File "C:\Python32\lib\urllib\request.py", line 150, in urlretrieve 
    return _urlopener.retrieve(url, filename, reporthook, data) 
    File "C:\Python32\lib\urllib\request.py", line 1597, in retrieve 
    block = fp.read(bs) 
ValueError: read of closed file 

Ich dachte, das ein vorübergehendes Problem sein könnte, so habe ich einige einfache Ausnahme wie so Handhabung:

import random 
import time 
import urllib.request 

host = "scholar.google.com" 
link = "/scholar.bib?q=info:K7uZdMSvdQ0J:scholar.google.com/&output=citation&hl=en&as_sdt=1,14&ct=citation&cd=0" 
url = "http://" + host + link 
filename = "cite0.bib" 
print(url) 
while True: 
    try: 
     print("Downloading...") 
     time.sleep(random.randint(0, 5)) 
     urllib.request.urlretrieve(url, filename) 
     break 
    except ValueError: 
     pass 

aber dies druckt nur Downloading... ad infinitum.

+0

Wenn Sie in "http: // scholar.google.com/robots.txt" suchen, können Sie sehen, dass Google das automatische Herunterladen dieser Seite verbietet. Und wenn Sie versuchen, 'wget' zu verwenden, erhalten Sie einen' 403 Forbidden' Fehler. Ich vermute, das passiert auch mit deinem Skript. –

+0

@senderle Es gibt keine API, also analysiere ich sie manuell. –

+0

@senderle, wahrscheinlich müssen Sie einen Cookie senden, um den Inhalt zu erhalten. –

Antwort

4

Ihre URL geben einen 403 Code Fehler und scheinbar urllib.request.urlretrieve ist es, alle HTTP-Fehler bei der Erkennung nicht gut, weil es urllib.request.FancyURLopener und diese neueste Versuch ist mit Fehler zu schlucken durch eine urlinfo statt Anhebung ein Fehler zurückgegeben.

Über das Update, wenn Sie noch verwenden urlretrieve möchten, können Sie FancyURLopener außer Kraft setzen wie folgt aus (Code enthalten, um auch den Fehler anzuzeigen):

import urllib.request 
from urllib.request import FancyURLopener 


class FixFancyURLOpener(FancyURLopener): 

    def http_error_default(self, url, fp, errcode, errmsg, headers): 
     if errcode == 403: 
      raise ValueError("403") 
     return super(FixFancyURLOpener, self).http_error_default(
      url, fp, errcode, errmsg, headers 
     ) 

# Monkey Patch 
urllib.request.FancyURLopener = FixFancyURLOpener 

url = "http://scholar.google.com/scholar.bib?q=info:K7uZdMSvdQ0J:scholar.google.com/&output=citation&hl=en&as_sdt=1,14&ct=citation&cd=0" 
urllib.request.urlretrieve(url, "cite0.bib") 

Else und das ist, was i empfehlen können Sie urllib.request.urlopen verwenden like so:

fp = urllib.request.urlopen('http://scholar.google.com/scholar.bib?q=info:K7uZdMSvdQ0J:scholar.google.com/&output=citation&hl=en&as_sdt=1,14&ct=citation&cd=0') 
with open("citi0.bib", "w") as fo: 
    fo.write(fp.read()) 
+0

Danke für die Hilfe. +1 und das Akzeptieren für das Affepatching und die allgemeine Hilfe, obwohl ich inzwischen gemerkt habe, dass 'robots.txt' das Herunterladen dieser Dateien nicht erlaubt. Ich habe komplett vergessen, das zu überprüfen. –