파이썬을 사용하여 HTTP를 통해 파일을 어떻게 다운로드합니까?


874

일정에 따라 웹 사이트에서 MP3 파일을 다운로드 한 다음 iTunes에 추가 한 팟 캐스트 XML 파일을 빌드 / 업데이트하는 데 사용하는 작은 유틸리티가 있습니다.

XML 파일을 작성 / 업데이트하는 텍스트 처리는 Python으로 작성됩니다. 그러나 Windows .bat파일 내부에서 wget을 사용 하여 실제 MP3 파일을 다운로드합니다. 전체 유틸리티를 파이썬으로 작성하는 것을 선호합니다.

내가 사용에 의존 왜 이렇게, 실제로 파이썬에서 파일을 다운로드 할 수있는 방법을 찾기 위해 노력 wget.

그렇다면 파이썬을 사용하여 파일을 어떻게 다운로드합니까?



아래의 많은 답변이 만족스러운 대체품이 아닙니다 wget. 무엇보다도 wget(1) 타임 스탬프를 유지합니다. (2) 자동으로 파일 이름을 URL에서 결정 .1하고 파일이 이미 존재하는 경우 (예를 들어)를 추가 하면 (3) 다른 옵션이 여러 개 있습니다 .wgetrc. 그중 하나를 원한다면 파이썬으로 직접 구현해야하지만 파이썬에서 호출하는 것이 더 간단합니다 wget.
ShreevatsaR

2
Python 3을위한 짧은 솔루션 :import urllib.request; s = urllib.request.urlopen('http://example.com/').read().decode()
Basj

답변:


450

Python 2에서는 표준 라이브러리와 함께 제공되는 urllib2를 사용하십시오.

import urllib2
response = urllib2.urlopen('http://www.example.com/')
html = response.read()

이것은 오류 처리를 제외한 라이브러리를 사용하는 가장 기본적인 방법입니다. 헤더 변경과 같은 더 복잡한 작업을 수행 할 수도 있습니다. 설명서는 여기 에서 찾을 수 있습니다.


11
제공 한 URL에 공백이 있으면 작동하지 않습니다. 이 경우 URL을 구문 분석하고 경로를 urlencode해야합니다.
Jason Sundram

91
다음은 파이썬 3 솔루션입니다 stackoverflow.com/questions/7243750/...
tommy.carstensen

6
참고로 경로를 urlencode하는 방법은urllib2.quote
André Puel

11
@JasonSundram : 공백이 있으면 URI가 아닙니다.
Zaz

1
더 큰 파일이있는 창에서는 작동하지 않습니다. 모든 블록을 읽어야합니다!
Avia

1115

하나 더 urlretrieve:

import urllib
urllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")

(Python 3 이상 사용 import urllib.requesturllib.request.urlretrieve)

"진행률 표시 줄"이있는 또 하나

import urllib2

url = "http://download.thinkbroadband.com/10MB.zip"

file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)

file_size_dl = 0
block_sz = 8192
while True:
    buffer = u.read(block_sz)
    if not buffer:
        break

    file_size_dl += len(buffer)
    f.write(buffer)
    status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
    status = status + chr(8)*(len(status)+1)
    print status,

f.close()

1
이상하게도, 이것은 urllib2 방법이 그렇지 않을 때 Windows에서 나를 위해 일했습니다. urllib2 방법은 Mac에서 작동했습니다.
InFreefall

6
버그 : file_size_dl + = block_sz는 + = len (buffer)이어야합니다. 마지막 읽기는 종종 전체 block_sz가 아니기 때문입니다. 또한 Windows에서는 출력 파일이 텍스트 파일이 아닌 경우 "wb"로 출력 파일을 열어야합니다.
가지 Jeff

1
나도 urllib와 urllib2는 작동하지 않았지만 urlretrieve는 잘 작동하고 좌절되었다-고마워 :)
funk-shun

2
if not os.path.isfile(file_name):Podcast를 덮어 쓰지 않도록 모든 것을 감싸십시오 (file_name 정의 제외) ! .html 파일에있는 URL을 사용하여 cronjob으로 실행할 때 유용
Sriram Murali

2
@PabloG 그것은 지금 31 표보다 약간 더 큽니다.) 어쨌든, 상태 표시 줄이 재미있어서 +1
Cinder

340

2012 년에는 Python 요청 라이브러리를 사용하십시오.

>>> import requests
>>> 
>>> url = "http://download.thinkbroadband.com/10MB.zip"
>>> r = requests.get(url)
>>> print len(r.content)
10485760

당신은 pip install requests그것을 얻기 위해 실행할 수 있습니다 .

API는 훨씬 단순하기 때문에 요청은 대안에 비해 많은 장점이 있습니다. 인증을 수행해야하는 경우 특히 그렇습니다. 이 경우 urllib 및 urllib2는 매우 직관적이지 않고 고통 스럽습니다.


2015-12-30

사람들은 진행률 표시 줄에 감탄을 표명했습니다. 멋지다. 현재 다음과 같은 몇 가지 상용 솔루션이 있습니다 tqdm.

from tqdm import tqdm
import requests

url = "http://download.thinkbroadband.com/10MB.zip"
response = requests.get(url, stream=True)

with open("10MB", "wb") as handle:
    for data in tqdm(response.iter_content()):
        handle.write(data)

이것은 본질적으로 30 개월 전에 설명한 @kvance 구현입니다.


zip 파일이 실제로 파일이 많은 폴더 인 경우 어떻게 저장하거나 추출합니까?
Abdul Muneer

6
큰 파일을 처리하거나 모든 것이 메모리에 저장됩니까? 아니면 큰 메모리 요구 사항없이 파일에 쓸 수 있습니까?
bibstha

8
요청에서 stream = True를 설정하여 큰 파일을 스트리밍 할 수 있습니다. 그런 다음 응답에서 iter_content ()를 호출하여 한 번에 청크를 읽을 수 있습니다.
kvance

7
URL 라이브러리에 파일 압축 해제 기능이 필요한 이유는 무엇입니까? URL에서 파일을 읽고 저장 한 다음 보트를 떠 다니는 방법으로 압축을 푸십시오. 또한 zip 파일은 창에 표시된 것처럼 '폴더'가 아닙니다. 파일입니다.
Harel

2
@Ali : r.text: 텍스트 또는 유니 코드 컨텐츠 용. 유니 코드로 반환됩니다. r.content: 이진 콘텐츠의 경우. 바이트로 반환됩니다. 여기에서 읽어보십시오 : docs.python-requests.org/en/latest/user/quickstart
hughdbrown

159
import urllib2
mp3file = urllib2.urlopen("http://www.example.com/songs/mp3.mp3")
with open('test.mp3','wb') as output:
  output.write(mp3file.read())

wb에서이 open('test.mp3','wb')파일을 열고 (기존의 모든 파일을 삭제합니다) 당신은 단지 텍스트 대신 그것으로 데이터를 저장할 수 있도록 바이너리 모드로.


30
이 솔루션의 단점은 디스크에 저장하기 전에 전체 파일이 램에로드된다는 것입니다. 램이 제한된 라우터와 같은 작은 시스템에서 큰 파일에이 파일을 사용할 경우 명심해야합니다.
tripplet

2
@tripplet 그래서 어떻게 고칠까요?
Lucas Henrique

11
전체 파일을 메모리로 읽는 것을 피하려면 file.read읽을 바이트 수인 인수를 전달하십시오 . 참조 : gist.github.com/hughdbrown/c145b8385a2afa6570e2
hughdbrown

@ hughdbrown 스크립트가 유용하다는 것을 알았지 만 한 가지 질문이 있습니다. 후 처리에 파일을 사용할 수 있습니까? OpenCV로 처리하려는 jpg 파일을 다운로드한다고 가정하면 'data'변수를 사용하여 계속 작업 할 수 있습니까? 또는 다운로드 한 파일에서 다시 읽어야합니까?
로드리고 E. 프린시 페

5
shutil.copyfileobj(mp3file, output)대신 사용하십시오 .
Aurélien Ooms

129

파이썬 3

  • urllib.request.urlopen

    import urllib.request
    response = urllib.request.urlopen('http://www.example.com/')
    html = response.read()
  • urllib.request.urlretrieve

    import urllib.request
    urllib.request.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')

    참고 : 설명서에 따르면 urllib.request.urlretrieve"레거시 인터페이스"이며 "향후 사용되지 않을 수 있습니다"( gerrit 감사합니다 )

파이썬 2


2
확실히 시간이 걸렸지 만, 마침내 파이썬 stdlib에서 기대할 수있는 쉬운 API가 있습니다 :)
ThorSummoner

python3에 대한 훌륭한 답변입니다. docs.python.org/3/library/…
Edouard Thiel

@EdouardThiel urllib.request.urlretrieve위 를 클릭 하면 정확한 링크로 연결됩니다. 건배!
bmaupin

2
urllib.request.urlretrieve"레거시 인터페이스"로 문서화되어 있으며 "미래에 더 이상 사용되지 않을 수 있습니다".
17:32에 gerrit

@gerrit 메모를 추가했습니다. 감사합니다.
bmaupin


21

Python 2/3 용 개선 된 PabloG 코드 버전 :

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import ( division, absolute_import, print_function, unicode_literals )

import sys, os, tempfile, logging

if sys.version_info >= (3,):
    import urllib.request as urllib2
    import urllib.parse as urlparse
else:
    import urllib2
    import urlparse

def download_file(url, dest=None):
    """ 
    Download and save a file specified by url to dest directory,
    """
    u = urllib2.urlopen(url)

    scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
    filename = os.path.basename(path)
    if not filename:
        filename = 'downloaded.file'
    if dest:
        filename = os.path.join(dest, filename)

    with open(filename, 'wb') as f:
        meta = u.info()
        meta_func = meta.getheaders if hasattr(meta, 'getheaders') else meta.get_all
        meta_length = meta_func("Content-Length")
        file_size = None
        if meta_length:
            file_size = int(meta_length[0])
        print("Downloading: {0} Bytes: {1}".format(url, file_size))

        file_size_dl = 0
        block_sz = 8192
        while True:
            buffer = u.read(block_sz)
            if not buffer:
                break

            file_size_dl += len(buffer)
            f.write(buffer)

            status = "{0:16}".format(file_size_dl)
            if file_size:
                status += "   [{0:6.2f}%]".format(file_size_dl * 100 / file_size)
            status += chr(13)
            print(status, end="")
        print()

    return filename

if __name__ == "__main__":  # Only run if this file is called directly
    print("Testing with 10MB download")
    url = "http://download.thinkbroadband.com/10MB.zip"
    filename = download_file(url)
    print(filename)

너무 오래된 기능이 아니기 때문에 첫 번째 줄에서 괄호를 제거합니다.
Arpad Horvath

21

간단하면서도 Python 2 & Python 3호환되는 방법은 six라이브러리 와 함께 제공됩니다 .

from six.moves import urllib
urllib.request.urlretrieve("http://www.example.com/songs/mp3.mp3", "mp3.mp3")

1
이것은 2 + 3 호환성을 위해 가장 좋은 방법입니다.
푸시

21
import os,requests
def download(url):
    get_response = requests.get(url,stream=True)
    file_name  = url.split("/")[-1]
    with open(file_name, 'wb') as f:
        for chunk in get_response.iter_content(chunk_size=1024):
            if chunk: # filter out keep-alive new chunks
                f.write(chunk)


download("https://example.com/example.jpg")

17

wget을 바로이 목적을 위해 순수한 파이썬 라이브러리를. 버전 2.0부터 이러한 기능 으로 향상 urlretrieve되었습니다 .


3
사용자 정의 파일 이름으로 저장할 옵션이 없습니까?
Alex

2
@ 알렉스는 버전 2.1에 -o filename 옵션을 추가
아나톨리 techtonik

Cygwin에서이 모듈을 사용할 때 진행률 표시 줄이 나타나지 않습니다.
Joe Coder

GNU wget에서와 같이 혼동을 피하기 위해 에서 -o로 변경해야합니다 -O. 또는 두 옵션 모두 유효해야합니다.
erik

@eric wget.pyreal 대신 현재 위치에서 교체 하고 싶은지 잘 모르겠습니다 wget. 는 -o이미 다르게 동작 -이와 호환 curl이 방법. 설명서에 메모가 문제 해결에 도움이됩니까? 또는 이러한 이름을 가진 유틸리티가 명령 줄과 호환되는 필수 기능입니까?
anatoly techtonik

15

다음은 파이썬에서 파일을 다운로드하기 위해 가장 일반적으로 사용되는 호출입니다.

  1. urllib.urlretrieve ('url_to_file', file_name)

  2. urllib2.urlopen('url_to_file')

  3. requests.get(url)

  4. wget.download('url', file_name)

참고 : urlopenurlretrieve대용량 파일 (크기> 500MB의) 다운로드 상대적으로 나쁜 수행 발견된다. requests.get다운로드가 완료 될 때까지 파일을 메모리에 저장합니다.


14

Corey에 동의합니다 .urlurl2는 urllib 보다 완벽하며 더 복잡한 작업을 수행하려는 경우 사용되는 모듈이어야하지만 대답을보다 완벽하게하려면 urllib가 기본 사항을 원할 경우 더 간단한 모듈입니다.

import urllib
response = urllib.urlopen('http://www.example.com/sound.mp3')
mp3 = response.read()

잘 작동합니다. 또는 "응답"객체를 다루지 않으려면 read ()를 직접 호출 할 수 있습니다.

import urllib
mp3 = urllib.urlopen('http://www.example.com/sound.mp3').read()

10

python3에서는 urllib3 및 shutil libraires를 사용할 수 있습니다. pip 또는 pip3을 사용하여 다운로드하십시오 (python3이 기본값인지 여부에 따라 다름)

pip3 install urllib3 shutil

그런 다음이 코드를 실행하십시오.

import urllib.request
import shutil

url = "http://www.somewebsite.com/something.pdf"
output_file = "save_this_name.pdf"
with urllib.request.urlopen(url) as response, open(output_file, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)

다운로드 urllib3했지만 urllib코드에서 사용하십시오 .


7

urlretrieve를 사용하여 진행 상태 피드백을 얻을 수도 있습니다.

def report(blocknr, blocksize, size):
    current = blocknr*blocksize
    sys.stdout.write("\r{0:.2f}%".format(100.0*current/size))

def downloadFile(url):
    print "\n",url
    fname = url.split('/')[-1]
    print fname
    urllib.urlretrieve(url, fname, report)

7

wget이 설치되어 있으면 parallel_sync를 사용할 수 있습니다.

pip install parallel_sync

from parallel_sync import wget
urls = ['http://something.png', 'http://somthing.tar.gz', 'http://somthing.zip']
wget.download('/tmp', urls)
# or a single file:
wget.download('/tmp', urls[0], filenames='x.zip', extract=True)

문서 : https://pythonhosted.org/parallel_sync/pages/examples.html

이것은 매우 강력합니다. 파일을 병렬로 다운로드하고 실패시 다시 시도 할 수 있으며 원격 시스템에서 파일을 다운로드 할 수도 있습니다.


이것은 리눅스만을위한 것입니다
jjj

4

당신에게 속도 문제는, 내가 모듈을위한 작은 성능 테스트 한 경우 urllibwget,와 관련하여 wget나는 상태 표시 줄에 및없이 일단 한 번 시도했다. 테스트를 위해 3 가지 500MB 파일을 사용했습니다 (다른 파일-일부 캐싱이 발생할 가능성을 없애기 위해). python2를 사용하여 데비안 컴퓨터에서 테스트했습니다.

먼저 결과는 다음과 같습니다 (다른 실행에서 비슷 함).

$ python wget_test.py 
urlretrive_test : starting
urlretrive_test : 6.56
==============
wget_no_bar_test : starting
wget_no_bar_test : 7.20
==============
wget_with_bar_test : starting
100% [......................................................................] 541335552 / 541335552
wget_with_bar_test : 50.49
==============

테스트를 수행 한 방법은 "프로파일"데코레이터를 사용하는 것입니다. 이것은 전체 코드입니다.

import wget
import urllib
import time
from functools import wraps

def profile(func):
    @wraps(func)
    def inner(*args):
        print func.__name__, ": starting"
        start = time.time()
        ret = func(*args)
        end = time.time()
        print func.__name__, ": {:.2f}".format(end - start)
        return ret
    return inner

url1 = 'http://host.com/500a.iso'
url2 = 'http://host.com/500b.iso'
url3 = 'http://host.com/500c.iso'

def do_nothing(*args):
    pass

@profile
def urlretrive_test(url):
    return urllib.urlretrieve(url)

@profile
def wget_no_bar_test(url):
    return wget.download(url, out='/tmp/', bar=do_nothing)

@profile
def wget_with_bar_test(url):
    return wget.download(url, out='/tmp/')

urlretrive_test(url1)
print '=============='
time.sleep(1)

wget_no_bar_test(url2)
print '=============='
time.sleep(1)

wget_with_bar_test(url3)
print '=============='
time.sleep(1)

urllib 가장 빠른 것 같습니다


바가 시간을 너무 많이 늘리려면 후드 아래에 완전히 끔찍한 일이 있어야합니다.
Alistair Carscadden

4

완전성을 위해 subprocess패키지를 사용하여 파일을 검색하기 위해 모든 프로그램을 호출 할 수도 있습니다 . 파일 검색 전용 프로그램은와 같은 Python 함수보다 강력 urlretrieve합니다. 예를 들어, wget디렉토리를 재귀 적으로 다운로드 할 수 있고 ( -R), FTP, 리디렉션, HTTP 프록시를 처리하고, 기존 파일을 다시 다운로드 하지 않을 수 있으며 ( -nc) aria2다중 연결 다운로드를 수행하여 다운로드 속도를 높일 수 있습니다.

import subprocess
subprocess.check_output(['wget', '-O', 'example_output_file.html', 'https://example.com'])

Jupyter Notebook에서는 다음 !구문을 사용하여 프로그램을 직접 호출 할 수도 있습니다 .

!wget -O example_output_file.html https://example.com

3

소스 코드는 다음과 같습니다.

import urllib
sock = urllib.urlopen("http://diveintopython.org/")
htmlSource = sock.read()                            
sock.close()                                        
print htmlSource  

3

Python 2 및 3에서 PycURL 을 사용할 수 있습니다 .

import pycurl

FILE_DEST = 'pycurl.html'
FILE_SRC = 'http://pycurl.io/'

with open(FILE_DEST, 'wb') as f:
    c = pycurl.Curl()
    c.setopt(c.URL, FILE_SRC)
    c.setopt(c.WRITEDATA, f)
    c.perform()
    c.close()

2

바닐라 파이썬 2 또는 파이썬 3에서 작동하는 다음을 작성했습니다.


import sys
try:
    import urllib.request
    python3 = True
except ImportError:
    import urllib2
    python3 = False


def progress_callback_simple(downloaded,total):
    sys.stdout.write(
        "\r" +
        (len(str(total))-len(str(downloaded)))*" " + str(downloaded) + "/%d"%total +
        " [%3.2f%%]"%(100.0*float(downloaded)/float(total))
    )
    sys.stdout.flush()

def download(srcurl, dstfilepath, progress_callback=None, block_size=8192):
    def _download_helper(response, out_file, file_size):
        if progress_callback!=None: progress_callback(0,file_size)
        if block_size == None:
            buffer = response.read()
            out_file.write(buffer)

            if progress_callback!=None: progress_callback(file_size,file_size)
        else:
            file_size_dl = 0
            while True:
                buffer = response.read(block_size)
                if not buffer: break

                file_size_dl += len(buffer)
                out_file.write(buffer)

                if progress_callback!=None: progress_callback(file_size_dl,file_size)
    with open(dstfilepath,"wb") as out_file:
        if python3:
            with urllib.request.urlopen(srcurl) as response:
                file_size = int(response.getheader("Content-Length"))
                _download_helper(response,out_file,file_size)
        else:
            response = urllib2.urlopen(srcurl)
            meta = response.info()
            file_size = int(meta.getheaders("Content-Length")[0])
            _download_helper(response,out_file,file_size)

import traceback
try:
    download(
        "https://geometrian.com/data/programming/projects/glLib/glLib%20Reloaded%200.5.9/0.5.9.zip",
        "output.zip",
        progress_callback_simple
    )
except:
    traceback.print_exc()
    input()

노트:

  • "진행률 표시 줄"콜백을 지원합니다.
  • 다운로드는 내 웹 사이트에서 4MB 테스트 .zip입니다.

좋은 작품, jupyter를 통해 실행 내가 :-) 원하는 것을 얻었다
사미르 Ouldsaadi에게

1

이것은 조금 늦을 수도 있지만 pabloG의 코드를 보았고 os.system ( 'cls')을 추가하여 멋지게 보이도록 도울 수 없었습니다! 확인 해봐 :

    import urllib2,os

    url = "http://download.thinkbroadband.com/10MB.zip"

    file_name = url.split('/')[-1]
    u = urllib2.urlopen(url)
    f = open(file_name, 'wb')
    meta = u.info()
    file_size = int(meta.getheaders("Content-Length")[0])
    print "Downloading: %s Bytes: %s" % (file_name, file_size)
    os.system('cls')
    file_size_dl = 0
    block_sz = 8192
    while True:
        buffer = u.read(block_sz)
        if not buffer:
            break

        file_size_dl += len(buffer)
        f.write(buffer)
        status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
        status = status + chr(8)*(len(status)+1)
        print status,

    f.close()

Windows 이외의 환경에서 실행하는 경우 'cls'이외의 다른 것을 사용해야합니다. MAC OS X 및 Linux에서는 'clear'해야합니다.


3
cls내 OS X 또는 내 Ubuntu 서버에서 아무것도하지 않습니다. 약간의 설명이 좋을 수 있습니다.
kqw

나는 clear리눅스에 사용해야 하거나 전체 명령 줄 출력을 지우는 대신 인쇄 줄을 더 잘 대체 해야한다고 생각합니다 .
Arijoon

4
이 답변은 다른 답변을 복사하고 더 이상 사용되지 않는 함수 ( os.system())에 호출을 추가 하여 하위 프로세스를 시작하여 플랫폼 별 명령 ( cls)을 사용하여 화면을 지 웁니다 . 어떻게 이런 일이 있습니까 어떤 upvotes을 ?? 완전히 쓸모없는 "답변"IMHO.
Corey Goldberg

1

urlretrieve 및 requests.get은 간단하지만 실제로는 그렇지 않습니다. 텍스트와 이미지를 포함한 커플 사이트에 대한 데이터를 가져 왔으므로 위의 두 가지 작업이 대부분의 작업을 해결할 수 있습니다. 그러나보다 보편적 인 솔루션을 위해서는 urlopen을 사용하는 것이 좋습니다. Python 3 표준 라이브러리에 포함되어 있으므로 사이트 패키지를 사전 설치하지 않고도 Python 3을 실행하는 모든 컴퓨터에서 코드를 실행할 수 있습니다.

import urllib.request
url_request = urllib.request.Request(url, headers=headers)
url_connect = urllib.request.urlopen(url_request)

#remember to open file in bytes mode
with open(filename, 'wb') as f:
    while True:
        buffer = url_connect.read(buffer_size)
        if not buffer: break

        #an integer value of size of written data
        data_wrote = f.write(buffer)

#you could probably use with-open-as manner
url_connect.close()

이 답변은 Python을 사용하여 http를 통해 파일을 다운로드 할 때 HTTP 403 Forbidden에 대한 솔루션을 제공합니다. 나는 요청과 urllib 모듈 만 시도했지만 다른 모듈은 더 나은 것을 제공 할 수 있지만 이것이 대부분의 문제를 해결하는 데 사용한 것입니다.


0

늦은 답변이지만 python>=3.6다음을 사용할 수 있습니다.

import dload
dload.save(url)

다음을 사용 dload하여 설치 :

pip3 install dload

0

웹 페이지에서 모든 파일을 다운로드하고 싶었습니다. 시도 wget했지만 실패했지만 파이썬 경로를 결정 하고이 스레드를 찾았습니다.

그것을 읽은 후에 PabloGStansoupget 의 탁월한 답변을 확장 하고 유용한 옵션을 추가 하여 약간의 명령 줄 응용 프로그램을 만들었습니다 .

BeatifulSoup 을 사용 하여 페이지의 모든 URL을 수집 한 다음 원하는 확장명을 가진 URL을 다운로드합니다. 마지막으로 여러 파일을 병렬로 다운로드 할 수 있습니다.

여기있어:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import (division, absolute_import, print_function, unicode_literals)
import sys, os, argparse
from bs4 import BeautifulSoup

# --- insert Stan's script here ---
# if sys.version_info >= (3,): 
#...
#...
# def download_file(url, dest=None): 
#...
#...

# --- new stuff ---
def collect_all_url(page_url, extensions):
    """
    Recovers all links in page_url checking for all the desired extensions
    """
    conn = urllib2.urlopen(page_url)
    html = conn.read()
    soup = BeautifulSoup(html, 'lxml')
    links = soup.find_all('a')

    results = []    
    for tag in links:
        link = tag.get('href', None)
        if link is not None: 
            for e in extensions:
                if e in link:
                    # Fallback for badly defined links
                    # checks for missing scheme or netloc
                    if bool(urlparse.urlparse(link).scheme) and bool(urlparse.urlparse(link).netloc):
                        results.append(link)
                    else:
                        new_url=urlparse.urljoin(page_url,link)                        
                        results.append(new_url)
    return results

if __name__ == "__main__":  # Only run if this file is called directly
    # Command line arguments
    parser = argparse.ArgumentParser(
        description='Download all files from a webpage.')
    parser.add_argument(
        '-u', '--url', 
        help='Page url to request')
    parser.add_argument(
        '-e', '--ext', 
        nargs='+',
        help='Extension(s) to find')    
    parser.add_argument(
        '-d', '--dest', 
        default=None,
        help='Destination where to save the files')
    parser.add_argument(
        '-p', '--par', 
        action='store_true', default=False, 
        help="Turns on parallel download")
    args = parser.parse_args()

    # Recover files to download
    all_links = collect_all_url(args.url, args.ext)

    # Download
    if not args.par:
        for l in all_links:
            try:
                filename = download_file(l, args.dest)
                print(l)
            except Exception as e:
                print("Error while downloading: {}".format(e))
    else:
        from multiprocessing.pool import ThreadPool
        results = ThreadPool(10).imap_unordered(
            lambda x: download_file(x, args.dest), all_links)
        for p in results:
            print(p)

사용법의 예는 다음과 같습니다.

python3 soupget.py -p -e <list of extensions> -d <destination_folder> -u <target_webpage>

실제 예제를보고 싶다면 :

python3 soupget.py -p -e .xlsx .pdf .csv -u https://healthdata.gov/dataset/chemicals-cosmetics
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.