Gestor de descàrregues multifils senzill a Python

Gestor de descàrregues multifils senzill a Python

A Gestor de descàrregues és bàsicament un programa informàtic dedicat a la tasca de descarregar fitxers autònoms d'Internet. Aquí crearem un gestor de descàrregues senzill amb l'ajuda de fils a Python. Mitjançant el multi-threading, un fitxer es pot descarregar en forma de trossos simultàniament des de diferents fils. Per implementar-ho, crearem una eina de línia d'ordres senzilla que accepti l'URL del fitxer i després el descarregui.

Requisits previs: màquina Windows amb Python instal·lat.

Configuració

Baixeu els paquets esmentats a continuació des del indicador d'ordres.

1. Paquet de clics: Click és un paquet de Python per crear interfícies de línia d'ordres precioses amb el mínim codi necessari. És el kit de creació d'interfície de línia d'ordres.

pip install feu clic

2. Paquet de sol·licituds: En aquesta eina anem a descarregar un fitxer basat en l'URL (adreces HTTP). Requests és una biblioteca HTTP escrita en Python que us permet enviar sol·licituds HTTP. Podeu afegir capçaleres a fitxers i paràmetres de dades de diverses parts amb diccionaris senzills de Python i accedir a les dades de resposta de la mateixa manera.

sol·licituds d'instal·lació de pip

3. Paquet de fils: per treballar amb fils necessitem el paquet de threads.

rosca d'instal·lació de pip

Implementació

Nota:

El programa s'ha dividit en parts perquè sigui fàcil d'entendre. Assegureu-vos que no us perdeu cap part del codi mentre executeu el programa.

Pas 1: importa els paquets necessaris

Aquests paquets proporcionen les eines necessàries per fer que les sol·licituds web gestionen les entrades de la línia d'ordres i creïn fils.

Python
   import   click   import   requests   import   threading   

Pas 2: creeu la funció de gestor

Cada fil executarà aquesta funció per descarregar el seu fragment específic del fitxer. Aquesta funció s'encarrega de sol·licitar només un interval específic de bytes i escriure'ls a la posició correcta del fitxer.

Python
   def   Handler  (  start     end     url     filename  ):   headers   =   {  'Range'  :   f  'bytes=  {  start  }  -  {  end  }  '  }   r   =   requests  .  get  (  url     headers  =  headers     stream  =  True  )   with   open  (  filename     'r+b'  )   as   fp  :   fp  .  seek  (  start  )   fp  .  write  (  r  .  content  )   

Pas 3: definiu la funció principal amb el clic

Converteix la funció en una utilitat de línia d'ordres. Això defineix com els usuaris interactuen amb l'script des de la línia d'ordres.

Python
   #Note: This code will not work on online IDE   @click  .  command  (  help  =  'Downloads the specified file with given name using multi-threading'  )   @click  .  option  (  '--number_of_threads'     default  =  4     help  =  'Number of threads to use'  )   @click  .  option  (  '--name'     type  =  click  .  Path  ()   help  =  'Name to save the file as (with extension)'  )   @click  .  argument  (  'url_of_file'     type  =  str  )   def   download_file  (  url_of_file     name     number_of_threads  ):   

Pas 4: Definiu el nom del fitxer i determineu la mida del fitxer

Necessitem la mida del fitxer per dividir la descàrrega entre fils i assegurar-nos que el servidor admet descàrregues a intervals.

Python
    r   =   requests  .  head  (  url_of_file  )   file_name   =   name   if   name   else   url_of_file  .  split  (  '/'  )[  -  1  ]   try  :   file_size   =   int  (  r  .  headers  [  'Content-Length'  ])   except  :   print  (  'Invalid URL or missing Content-Length header.'  )   return   

Pas 5: preassigneu l'espai de fitxers

L'assignació prèvia garanteix que el fitxer tingui la mida correcta abans d'escriure fragments en intervals de bytes específics.

Python
    part   =   file_size   //   number_of_threads   with   open  (  file_name     'wb'  )   as   fp  :   fp  .  write  (  b  '    '   *   file_size  )   

Pas 6: crear fils

Els fils tenen assignats intervals de bytes específics per descarregar-los en paral·lel.

Python
    threads   =   []   for   i   in   range  (  number_of_threads  ):   start   =   part   *   i   end   =   file_size   -   1   if   i   ==   number_of_threads   -   1   else   (  start   +   part   -   1  )   t   =   threading  .  Thread  (  target  =  Handler     kwargs  =  {   'start'  :   start     'end'  :   end     'url'  :   url_of_file     'filename'  :   file_name   })   threads  .  append  (  t  )   t  .  start  ()   

Pas 7: uneix fils

Assegura que tots els fils s'han completat abans que finalitzi el programa.

Python
    for   t   in   threads  :   t  .  join  ()   print  (  f  '  {  file_name  }   downloaded successfully!'  )   if   __name__   ==   '__main__'  :   download_file  ()   

Codi:

Python
   import   click   import   requests   import   threading   def   Handler  (  start     end     url     filename  ):   headers   =   {  'Range'  :   f  'bytes=  {  start  }  -  {  end  }  '  }   r   =   requests  .  get  (  url     headers  =  headers     stream  =  True  )   with   open  (  filename     'r+b'  )   as   fp  :   fp  .  seek  (  start  )   fp  .  write  (  r  .  content  )   @click  .  command  (  help  =  'Downloads the specified file with given name using multi-threading'  )   @click  .  option  (  '--number_of_threads'     default  =  4     help  =  'Number of threads to use'  )   @click  .  option  (  '--name'     type  =  click  .  Path  ()   help  =  'Name to save the file as (with extension)'  )   @click  .  argument  (  'url_of_file'     type  =  str  )   def   download_file  (  url_of_file     name     number_of_threads  ):   r   =   requests  .  head  (  url_of_file  )   if   name  :   file_name   =   name   else  :   file_name   =   url_of_file  .  split  (  '/'  )[  -  1  ]   try  :   file_size   =   int  (  r  .  headers  [  'Content-Length'  ])   except  :   print  (  'Invalid URL or missing Content-Length header.'  )   return   part   =   file_size   //   number_of_threads   with   open  (  file_name     'wb'  )   as   fp  :   fp  .  write  (  b  '    '   *   file_size  )   threads   =   []   for   i   in   range  (  number_of_threads  ):   start   =   part   *   i   # Make sure the last part downloads till the end of file   end   =   file_size   -   1   if   i   ==   number_of_threads   -   1   else   (  start   +   part   -   1  )   t   =   threading  .  Thread  (  target  =  Handler     kwargs  =  {   'start'  :   start     'end'  :   end     'url'  :   url_of_file     'filename'  :   file_name   })   threads  .  append  (  t  )   t  .  start  ()   for   t   in   threads  :   t  .  join  ()   print  (  f  '  {  file_name  }   downloaded successfully!'  )   if   __name__   ==   '__main__'  :   download_file  ()   


Hem acabat amb la part de codificació i ara seguiu les ordres que es mostren a continuació per executar el fitxer .py.

 python filename.py –-help  

Sortida:

ajuda_sortidanomfitxer python.py –-help


Aquesta ordre mostra l'ús de l'eina d'ordres de clic i les opcions que l'eina pot acceptar. A continuació es mostra l'ordre d'exemple on intentem descarregar un fitxer d'imatge jpg des d'una URL i també donem un nom i nombre_de_fils.

Captura de pantalla-2025-04-07-155058ordre de mostra per descarregar un jpg

Després d'executar-ho tot amb èxit, podreu veure el vostre fitxer (flower.webp en aquest cas) al directori de carpetes com es mostra a continuació:

Captura de pantalla-2025-04-07-155750directori

Finalment, hem acabat amb èxit i aquesta és una de les maneres de crear un gestor de descàrregues multiprocés senzill a Python.