Urllib ile bir sitenin html kodlarını çekebiliyoruz peki ya fotoğraf veya dosya aktarımı için bir yöntem var mı?
python3-de urllib.request kutuphanesini kullanarak resim veya dosya indirmek mumkun.Ornek olarak,
import urllib.request
adres="https://upload.wikimedia.org/wikipedia/commons/9/9b/Python_molurus_bivittatus_%283%29.jpg"
urllib.request.urlretrieve(adres,'python.jpeg')
Bu zaman resim dosyasi python dosyanizin oldugu dizine yuklenecekdir
Hamid Bey’in önerdiği örneğe ilaveten aşağıdaki kodları da inceleyebilirsiniz. Aşağıdaki yöntemle download işlem bilgileri edinebilirsiniz.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import time
import urllib.request
import ssl
class Progress:
"""İşlem bilgisi sınıfı. Download için veya yinelenebilir
herhangi bir işlem için işlem bilgilerini anlık olarak gösterir."""
@staticmethod
def info(size, count, now):
"""İşlem bilgisini anlık olarak ekrana bastıran fonksiyon."""
print(
"\r|{}{}| {} %, {} b, {} s, {} b/s, {} s remaining."
.format(
# Tamamlananın toplama olan oranıyla "#" işaretinin adedi değişecek.
# 25 karakterlik bir alan ayrıldı. Daha fazla da ayırabiliriz
# Ama bilgiler ekrana sığsın istiyoruz
"#" * int(25 * count / size),
# 25 karakterlik alandan an içinde değişen "#" alanını çıkarıp,
# boşluk alanını hesaplıyoruz.
# Tamamlanma yüzdesi arttıkça boşluklar azalacak, # karakteri artacak.
" " * (25 - int(25 * count / size)),
# Tamamlanma yüzdesi
int(100 * count / size),
# Tamamlanan
count,
# Geçen zaman
int(time.time() - now),
# Aktarma hızı: tamamlanan / geçen zaman
int(count / (time.time() - now)),
# Kalan zaman: (Toplam / aktarma hızı) - geçen zaman
int(size / (count / (time.time() - now))) - int(time.time() - now)
),
flush=True,
end=""
)
@classmethod
"""urllib ile veri çekme"""
def urlopen(cls, url, file):
data = urllib.request.urlopen(
url=url,
context=ssl.SSLContext(ssl.PROTOCOL_SSLv23)
)
size = int(data.headers.get("content-length"))
with open(file, "wb") as f:
count = 0
now = time.time()
time.sleep(0.01)
for i in data:
count += len(i)
f.write(i)
cls.info(
size=size,
count=count,
now=now
)
print()
@classmethod
def reqget(cls, url, file):
"""requests ile veri çekme"""
import requests
data = requests.get(
url,
stream=True
)
size = int(data.headers.get("content-length"))
with open(file, "wb") as f:
count = 0
now = time.time()
time.sleep(0.01)
for i in data.iter_content(chunk_size=4096):
count += len(i)
f.write(i)
cls.info(
size=size,
count=count,
now=now
)
print()
Şimdi diyelim yukarıdaki sınıf, Progress.py adlı bir dosyanın içinde, biz de Progress.py’nin bulunduğu dizinde uç birimi açtık ve Python’a girdik:
>>> from Progress import Progress
>>> url = "https://docs.scipy.org/doc/scipy-0.16.0/scipy-ref-0.16.0.pdf"
>>> Progress.urlopen(url, "scipy.pdf")
|#########################| 100 %, 34562303 b, 88 s, 392701 b/s, 0 s remaining.
>>>
>>> Progress.reqget(url, "scipy.pdf")
|#########################| 100 %, 34562303 b, 62 s, 554213 b/s, 0 s remaining.
>>>
Her iki işlem de benzerdir.
Ek bilgi: Ayrıca yazdığımız işlem bilgisi sınıfı her türlü yineleme işlemi için de kullanılabilir.
Örnek-1: Sınıfa aşağıdaki “number” metodu dahil edilirse, onun için de kullanılabilir:
@classmethod
def number(cls, size):
count = 0
now = time.time()
time.sleep(0.01)
for i in range(size):
count += 1
cls.info(
size=size,
count=count,
now=now
)
print()
Kullanımı:
>>> Progress.number(100000)
|#########################| 100 %, 100000 b, 1 s, 52692 b/s, 0 s remaining.
>>>
Örnek-2: Sınıfa aşağıdaki “iterable” metodu dahil edilirse onun için de kullanılır.
@classmethod
def iterable(cls, array):
size = len(array)
count = 0
now = time.time()
time.sleep(0.01)
for i in range(size):
count += 1
cls.info(
size=size,
count=count,
now=now
)
print()
Kullanımı:
>>> Progress.iterable([i for i in range(1000000)])
|#########################| 100 %, 1000000 b, 18 s, 53468 b/s, 0 s remaining.
>>>
Örnek-3: Dosya kopyalama işlemleri için de kullanılabilir:
@classmethod
def copyfile(cls, source, target):
with open(source, "rb") as f1:
with open(target, "wb") as f2:
data = f1.read()
f1.seek(0)
size = len(data)
count = 0
now = time.time()
time.sleep(0.01)
for i in f1:
count += len(i)
f2.write(i)
cls.info(
size=size,
count=count,
now=now
)
print()
@classmethod
def copyfiles(cls, source, target):
if not os.path.exists(target):
os.mkdir(target)
for i, j, k in os.walk(source):
if i != source:
os.makedirs(
os.sep.join(
[
target,
i[len(source) + 1:]
]
)
)
for m in k:
cls.copyfile(
source=os.sep.join([i, m]),
target=os.sep.join(
[
target,
os.sep.join([i, m])[len(source) + 1:]
]
)
)
Kullanımı:
>>> import os
>>> source = os.getcwd() + "/Export"
>>> target = "/home/tanberk/Masaüstü/Export"
>>> Progress.copyfiles(source, target)
|#########################| 100 %, 9296204 b, 1 s, 7262167 b/s, 0 s remaining.
|#########################| 100 %, 37130 b, 0 s, 3615762 b/s, 0 s remaining.
|#########################| 100 %, 15868 b, 0 s, 1396927 b/s, 0 s remaining.
|#########################| 100 %, 425 b, 0 s, 41811 b/s, 0 s remaining.
|#########################| 100 %, 12444 b, 0 s, 879396 b/s, 0 s remaining.
|#########################| 100 %, 1484 b, 0 s, 106319 b/s, 0 s remaining.
|#########################| 100 %, 6353 b, 0 s, 618964 b/s, 0 s remaining.
>>>
Peki programı derlersek nereye inecek ve başka bir dizine indirebilir miyim?
Programı derlerseniz yine programınızın çalıştığı dizine iner. Dosya yolunu belirterek farklı bir dizine inmesini sağlayabilirsiniz:
import urllib.request
adres="https://upload.wikimedia.org/wikipedia/commons/9/9b/Python_molurus_bivittatus_%283%29.jpg"
urllib.request.urlretrieve(adres,'home/bir dizin/python.jpeg')
İyi çalışmalar.
Peki indirilen fotoğrafın ram üzerinde kalmasını nasıl sağlayabilirim?(Snapchat te olan gibi, fotoğrafı kaydetmeden.)
Snapchat’in fotoğrafı kaydetmediğini nereden biliyorsunuz? Hem buna niye ihtiyacınız var ki?
Merak ettiğiniz içinse io.StringIO sınıfını kullanabilirsiniz.
Bir yerde yazmıştım tarayıcı yazmayı düşünüyorum. Onun için sordum. Çünkü fotoğrafı kaydedersem bir de silmekle uğraşacağım.