Kaip atsisiųsti vaizdą naudojant užklausas

Bandau atsisiųsti ir išsaugoti vaizdą iš interneto naudojant „python requests modulį.

Čia yra naudojamas (darbo) kodas:

 img = urllib2.urlopen(settings.STATICMAP_URL.format(**data)) with open(path, 'w') as f: f.write(img.read()) 

Čia yra naujas (neveikiantis) kodas, naudojant requests :

 r = requests.get(settings.STATICMAP_URL.format(**data)) if r.status_code == 200: img = r.raw.read() with open(path, 'w') as f: f.write(img) 

Ar galite man padėti, kuris atributas iš atsakymo, kurį naudosite iš requests ?

287
30 окт. rinkinys shkschneider 30 okt. 2012-10-30 14:14 '12, 14:14 val. 2012-10-30 14:14
@ 12 atsakymų

Galite naudoti failo response.raw failą arba surūšiuoti atsakymą.

Jei norite naudoti failo tipo objekto response.raw , pagal nutylėjimą dekoduoti suspaustus atsakymus (naudojant GZIP arba deflaciją). Jūs galite priversti jį išpakuoti, nustatydami atributą „ decode_content į „ True ( requests nustato jį į „ False kad būtų galima kontroliuoti patį dekodavimą). Tada galite naudoti shutil.copyfileobj() , kad „Python“ perduotų duomenis į objekto failą:

 import requests import shutil r = requests.get(settings.STATICMAP_URL.format(**data), stream=True) if r.status_code == 200: with open(path, 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) 

Jei norite perjungti atsakymą, naudokite kilpą; Tokiu būdu iteracija užtikrina, kad duomenys šiame etape bus ištrinti:

 r = requests.get(settings.STATICMAP_URL.format(**data), stream=True) if r.status_code == 200: with open(path, 'wb') as f: for chunk in r: f.write(chunk) 

Jis skaitys duomenis 128 baitų gabalais; jei manote, kad kito fragmento dydis veikia geriau, naudokite „ Response.iter_content() metodą su pasirinktiniu bloko dydžiu:

 r = requests.get(settings.STATICMAP_URL.format(**data), stream=True) if r.status_code == 200: with open(path, 'wb') as f: for chunk in r.iter_content(1024): f.write(chunk) 

Atkreipkite dėmesį, kad reikia atidaryti paskirties failą dvejetainiu režimu, kad įsitikintumėte, jog python nesistengia ir verčia naujų linijų. Mes taip pat nustatėme stream=True , kad requests nepristatytų viso vaizdo į atmintį.

424
30 окт. atsakymą pateikė Martijn Pieters 30 sp 2012-10-30 14:18 '12 12:18 pm 2012-10-30 14:18

Gaukite užklausoje failą panašų objektą ir nukopijuokite jį į failą. Jis taip pat leidžia nedelsiant jį perskaityti atmintyje.

border=0
 import shutil import requests url = 'http://example.com/img.png' response = requests.get(url, stream=True) with open('img.png', 'wb') as out_file: shutil.copyfileobj(response.raw, out_file) del response 
182
04 авг. Oleh Prypin atsakymas rugpjūčio 04 d 2013-08-04 16:32 '13, 16:32 2013-08-04 16:32

Kaip apie tai, greitas sprendimas.

 import requests url = "http://craphound.com/images/1006884_2adf8fc7.jpg" response = requests.get(url) if response.status_code == 200: with open("/Users/apple/Desktop/sample.jpg", 'wb') as f: f.write(response.content) 
124
06 февр. atsakymą pateikė kiranbkrishna 06 vasaris 2014-02-06 09:33 '14 at 9:33 2014-02-06 09:33

Turiu tą patį poreikį įkelti vaizdus naudojant užklausas. Pirmą kartą bandžiau atsakyti Martijn Pieters, ir tai gerai veikia. Bet kai padariau šį paprastą funkciją, pastebėjau, kad jis naudoja tiek daug funkcijų skambučių, palyginti su urllib ir urllib2.

Tada bandžiau metodą, kurį rekomendavo užklausos modulio autorius:

 import requests from PIL import Image from StringIO import StringIO r = requests.get('https://example.com/image.jpg') i = Image.open(StringIO(r.content)) 

Tai žymiai sumažino funkcijų skambučių skaičių, kuris paskatino mano paraišką. Čia yra mano profilio kodas ir rezultatas.

 #!/usr/bin/python import requests from StringIO import StringIO from PIL import Image import profile def testRequest(): image_name = 'test1.jpg' url = 'http://example.com/image.jpg' r = requests.get(url, stream=True) with open(image_name, 'wb') as f: for chunk in r.iter_content(): f.write(chunk) def testRequest2(): image_name = 'test2.jpg' url = 'http://example.com/image.jpg' r = requests.get(url) i = Image.open(StringIO(r.content)) i.save(image_name) if __name__ == '__main__': profile.run('testUrllib()') profile.run('testUrllib2()') profile.run('testRequest()') 

TestRequest rezultatas:

 343080 function calls (343068 primitive calls) in 2.580 seconds 

Ir testRequest2 rezultatas:

 3129 function calls (3105 primitive calls) in 0.024 seconds 
63
07 авг. atsakymas suteiktas Zhenyi Zhang 07 rug . 2013-08-07 18:52 '13, 18:52, 2013-08-07 18:52

Tai gali būti lengviau nei naudojant requests . Tai yra vienintelis laikas, kai siūlau nenaudoti requests dirbti su HTTP failais.

Du įterpimai naudojant urllib :

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

Taip pat yra gražus Python modulis, vadinamas wget , kuris yra gana paprasta naudoti. Čia rasite .

Tai rodo dizaino paprastumą:

 >>> import wget >>> url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3' >>> filename = wget.download(url) 100% [................................................] 3841532 / 3841532> >> filename 'razorback.mp3' 

Mėgaukitės

Redaguoti: taip pat galite pridėti out parametrą, nurodant kelią.

 >>> out_filepath = <output_filepath> >>> filename = wget.download(url, out=out_filepath) 
38
23 нояб. Blairg23 atsakymas lapkričio 23 d. 2015-11-23 11:02 '15 at 11:02 2015-11-23 11:02

Šis kodo fragmentas įkelia failą.

Failas įrašomas su failo pavadinimu, kaip nurodyta nurodytame URL.

 import requests url = "http://beispiel.dort/ichbineinbild.jpg" filename = url.split("/")[-1] r = requests.get(url, timeout=0.5) if r.status_code == 200: with open(filename, 'wb') as f: f.write(r.content) 
18
07 апр. Katja Süss atsakymas 07 Bal 2017-04-07 22:42 '17, 10:42 pm 2017-04-07 22:42

Yra du pagrindiniai būdai:

  • Naudojant .content (paprasčiausias / oficialus) (žr. .content Zhang atsakymą ):

     import io # Note: io.BytesIO is StringIO.StringIO on Python2. import requests r = requests.get('http://lorempixel.com/400/200') r.raise_for_status() with io.BytesIO(r.content) as f: with Image.open(f) as img: img.show() 
  • .raw (žr. Martijn Pieters atsakymą ):

     import requests r = requests.get('http://lorempixel.com/400/200', stream=True) r.raise_for_status() r.raw.decode_content = True # Required to decompress gzip/deflate compressed responses. with PIL.Image.open(r.raw) as img: img.show() r.close() # Safety when stream=True ensure the connection is released. 

Abi datos nerodo pastebimo skirtumo.

12
31 мая '16 в 17:01 2016-05-31 17:01 atsakymas į „ Wernight “ gegužės 16 d. 17:01 2016-05-31 17:01

Čia yra patogesnis atsakymas, kuriame vis dar naudojamas srautas.

Tiesiog nustatykite šias funkcijas ir paskambinkite getImage() . Jis naudos tą patį failo pavadinimą, kaip ir URL, ir rašys į dabartinį numatytąjį katalogą, tačiau abu galima pakeisti.

 import requests from StringIO import StringIO from PIL import Image def createFilename(url, name, folder): dotSplit = url.split('.') if name == None: # use the same as the url slashSplit = dotSplit[-2].split('/') name = slashSplit[-1] ext = dotSplit[-1] file = '{}{}.{}'.format(folder, name, ext) return file def getImage(url, name=None, folder='./'): file = createFilename(url, name, folder) with open(file, 'wb') as f: r = requests.get(url, stream=True) for block in r.iter_content(1024): if not block: break f.write(block) def getImageFast(url, name=None, folder='./'): file = createFilename(url, name, folder) r = requests.get(url) i = Image.open(StringIO(r.content)) i.save(file) if __name__ == '__main__': # Uses Less Memory getImage('http://www.example.com/image.jpg') # Faster getImageFast('http://www.example.com/image.jpg') 

Prašymas getImage() pagrįstas atsakymu čia , o getImageFast() žarnos yra paremtos aukščiau pateiktu atsakymu.

4
06 апр. Chris Redford atsakymas, pateiktas 06 Bal 2014-04-06 19:08 '14, 19:08, 2014-04-06 19:08

Taip pat lengva importuoti vaizdus ir užklausas.

 from PIL import Image import requests img = Image.open(requests.get(url, stream = True).raw) img.save('img1.jpg') 
4
17 сент. Atsakymą pateikė Riccardo D 17 sep. 2018-09-17 11:33 '18 at 11:33 am 2018-09-17 11:33

Ketinu paskelbti atsakymą, nes neturiu pakankamai komentarų, kad pateiktumėte komentarą, bet su Wget, kuris buvo išsiųstas Blairg23, taip pat galite nurodyti kelio parametrą.

  wget.download(url, out=path) 
2
24 мая '16 в 16:50 2016-05-24 16:50 atsakymas pateiktas tik gegužės 24 d., 16 val. 16:50 2016-05-24 16:50

Kai bandau paleisti žemiau esantį kodą, vaizdas pasenęs, tačiau jo dydis visada ribojamas iki 34 KB.

 import requests import shutil r = requests.get(settings.STATICMAP_URL.format(**data), stream=True) if r.status_code == 200: with open(path, 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) 

Taip pat leiskite man žinoti, kokie nustatymai.STATICMAP_URL.format (** duomenys) yra, naudoju usl, o ne parametrus.STATICMAP_URL.format (** data)

2
03 июля '18 в 8:26 2018-07-03 08:26 atsakymas duotas logikos meilužiui liepos 3 d., 18 val. 8:26 ; 2018-07-03 08:26

Naudodamas toliau pateiktą metodą vaizdams įkelti.

  newlink = image.img['src'] print('Downloading image', index) try: response = requests.get(newlink, stream=True) sleep(1) with open(image_path, 'wb') as file: sleep(1) shutil.copyfileobj(response.raw, file) except Exception as e: print(e) print('Could not download image number ', index) 

Viskas veikia gerai, bet pastebėjau, kad kai kiekvieną dieną paleisiu scenarijų, po kelių dienų (5-7) kiekvienas vaizdas įkeliamas daug laiko. Kai tai atsitiko, aš uždariau pycharm ir iš naujo paleidžiau savo kompiuterį. Po to jis vėl veikia gerai.

Norėčiau sužinoti, ar kas nors žino, kodėl taip atsitiko.

Ačiū

0
01 февр. atsakymas pateikiamas mpantogi 01 vasaris 2019-02-01 12:09 '19 , 12:09 PM 2019-02-01 12:09

Kiti klausimai apie žymes arba Užduoti klausimą