Urllib ile indirme işlemi

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.
>>> 
2 Beğeni

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.

2 Beğeni

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.

1 Beğeni