2014-01-10 4 views
0

How to download a file using python in a 'smarter' way?에서이 코드를 받았습니까?URL이 지정된 파일을 다운로드하고 콘텐츠 처리와 동일한 파일 이름을 저장하십시오.

하지만 오류가 발생합니다 :

in download 
    r.close() 
    UnboundLocalError: local variable 'r' referenced before assignment 

이 또한 내가 파일 만 PDF해야 다운로드 할 수있는 조건을 추가하고 싶습니다.

import urllib2 
import shutil 
import urlparse 
import os 


def download(url, fileName=None): 
    def getFileName(url,openUrl): 
     if 'Content-Disposition' in openUrl.info(): 
      # If the response has Content-Disposition, try to get filename from it 
      cd = dict(map(lambda x: x.strip().split('=') if '=' in x else (x.strip(),''),openUrl.info()['Content-Disposition'].split(';'))) 
      if 'filename' in cd: 
       filename = cd['filename'].strip("\"'") 
       if filename: return filename 
     # if no filename was found above, parse it out of the final URL. 
    return os.path.basename(urlparse.urlsplit(openUrl.url)[2]) 

    req = urllib2.Request(url) 
    try: 
     r = urllib2.urlopen(req) 
    except urllib2.HTTPError, e: 
      print e.fp.read() 
    try: 
      fileName = fileName or getFileName(url,r) 
      with open(fileName, 'wb') as f: 
       shutil.copyfileobj(r,f) 
    finally: 
      r.close() 

download('http://www.altria.com/Documents/Altria_10Q_Filed10242013.pdf#?page=24') 

이 URL을 완전히 잘 작동 : http://www.gao.gov/new.items/d04641.pdf 그래서 내 질문은 일부 URL을 위해 일하지만, 위에서 언급 한 것과 같은 URL을 완전히 잘 작동하지 않는 이유입니다.

+1

당신은 당신의 문제를 설명했고, 당신은 샘플 프로그램을 포함했다. 좋습니다. 당신은 여전히 ​​SO 게시물의 핵심 요소 인 질문을 놓치고 있습니다. SO는 질의 응답 사이트입니다. 독자와 같은 독자는 질문을하고 다른 독자는 대답을 시도합니다. 귀하의 질문은 무엇인가? –

답변

-1

언 바운드 로컬 오류가 발생하기 전에 urllib2.urlopen (req)이 실패한 방법에 대해 설명하는 오류 메시지를 출력한다고 가정합니다. 그렇다면 print e.fp.read() 뒤에 줄에 raise을 추가하면 문제가 다르게 보일 것입니다.

+0

그것은 말합니다 : urllib2.HTTPError : 금지 HTTP 오류 403 : 금지 – blackmamba

+0

글쎄 거기에 문제가있어. 서버가 해당 페이지에 대한 스크립트 액세스를 거부합니다. – nmichaels

+0

누구든지이 것을 downvoted :? – nmichaels

0

이것은 범위 문제입니다. 함수의 시작 부분에서

는 정의

r=None 

다음, 대신 r.close()를 호출하는, 다음을 수행하십시오

if r: 
     r.close() 
+0

누구든지 아래로 투표하여 의견을 남길 수 있습니까? 원래 코드가 초기화되지 않았을지라도 "finally"블록에서 r에 대해 close()를 호출하려고합니다. 그게 있었는지 확인하는 것이 잘못된 무엇입니까? 원래의 포스터는 정상적으로 오류를 처리하려고 시도했으나 액세스 할 수없는 URL에 액세스하려고 시도하면 문제가 해결됩니다. –

+0

나는 그것을 downvote하지 않았다. 그러나 당신이 제안했던 것은 조용한 실패로 끝날 것이다. 결국 문제는 오류를 숨기는 방법이 아니라 오류가 발생한 이유입니다. 즉, 당신의 대답은 확실히 투표의 가치가 없었습니다. 대리인을 좀 만나. – nmichaels

+0

충분합니다. 그리고 고마워! –

0

무엇이 일어나고있는 것은 첫째 예외가 있다는 것이다 걸러 내기 : r이 정의되지 않았더라도 (예외가 발생했기 때문에) except urllib2.HTTPError 코드가 계속됩니다.

사용하고 싶습니다. r = urllib2.urlopen(req)가 성공했을 경우 귀하의 try/except 블록의 else 절은 나머지 코드를 실행합니다 :

def download(url, fileName=None): 
    def getFileName(url,openUrl): 
     if 'Content-Disposition' in openUrl.info(): 
      # If the response has Content-Disposition, try to get filename from it 
      cd = dict(map(lambda x: x.strip().split('=') if '=' in x else (x.strip(),''),openUrl.info()['Content-Disposition'].split(';'))) 
      if 'filename' in cd: 
       filename = cd['filename'].strip("\"'") 
       if filename: return filename 
     # if no filename was found above, parse it out of the final URL. 
     return os.path.basename(urlparse.urlsplit(openUrl.url)[2]) 

    req = urllib2.Request(url) 
    try: 
     r = urllib2.urlopen(req) 
    except urllib2.HTTPError, e: 
     print e.fp.read() 
    else: 
     try: 
      fileName = fileName or getFileName(url,r) 
      with open(fileName, 'wb') as f: 
       shutil.copyfileobj(r,f) 
     finally: 
      r.close() 
관련 문제