2012-07-17 19 views
6

này đơn giản Python 3 kịch bản:Làm cách nào để sửa một ValueError: đọc ngoại lệ của tệp đã đóng?

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) 

tăng ngoại lệ này:

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 

Tôi nghĩ điều này có thể là một vấn đề tạm thời, vì vậy tôi đã thêm một số ngoại lệ đơn giản xử lý như sau:

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 

nhưng điều này chỉ in Downloading... vô hạn.

+0

Nếu bạn tìm trong 'http: // scholar.google.com/robots.txt' bạn có thể thấy rằng Google cấm tải xuống tự động trang này. Và nếu bạn thử sử dụng 'wget', bạn sẽ gặp lỗi' 403 Forbidden'. Tôi nghi ngờ điều này cũng xảy ra với kịch bản của bạn. –

+0

@senderle Không có API, vì vậy tôi sẽ phân tích cú pháp theo cách thủ công. –

+0

@senderle, rất có thể bạn cần gửi cookie để tải nội dung. –

Trả lời

4

URL của bạn trả về một lỗi 403 mã và rõ ràng urllib.request.urlretrieve là không giỏi phát hiện tất cả các lỗi HTTP, bởi vì nó sử dụng urllib.request.FancyURLopener và thử mới nhất này nuốt lỗi bằng cách quay một urlinfo thay vì tăng một lỗi.

Về việc sửa chữa nếu bạn vẫn muốn sử dụng urlretrieve bạn có thể ghi đè lên FancyURLopener như thế này (mã bao gồm cũng để hiển thị lỗi):

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") 

khác và đây là những gì tôi khuyên bạn có thể sử dụng urllib.request.urlopen như vậy:

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

Cảm ơn sự giúp đỡ. 1 và chấp nhận cho việc vá khỉ và trợ giúp chung, mặc dù tôi đã nhận ra, theo nhận xét ở trên, rằng 'robots.txt' không cho phép tải xuống các tệp đó. Tôi hoàn toàn quên kiểm tra điều đó. –

Các vấn đề liên quan