По-долу е обяснено как да посочите URL адреса на изображение, ZIP, PDF или друг файл в Мрежата в Python, да го изтеглите и да го запазите като локален файл.
- Изтеглете изображения, като посочите URL адреса.
- Пример за код
urllib.request.urlopen()
:Отворен URL адресopen()
:Записване във файл в двоичен режим- По-прост пример за код
- Изтегляне на ZIP файлове, PDF файлове и др.
- Извлечете URL адреса на изображението в уеб страницата.
- Ако номерът е последователен
- Екстракт с Красива супа
- Пакетно изтегляне на множество изображения от списък с URL адреси
Изтеглете изображения, като посочите URL адреса.
Можете да използвате стандартната библиотека само за изтегляне на отделни файлове, като посочите техните URL адреси; не е необходима допълнителна инсталация.
Пример за код
По-долу е представен пример за функция, която изтегля и записва файл, като посочва URL адреса и пътя до местоназначението, както и нейното използване. Този код е малко по-обширен за целите на обяснението. По-долу е даден прост пример.
import os import pprint import time import urllib.error import urllib.request def download_file(url, dst_path): try: with urllib.request.urlopen(url) as web_file: data = web_file.read() with open(dst_path, mode='wb') as local_file: local_file.write(data) except urllib.error.URLError as e: print(e)
url = 'https://www.python.org/static/img/python-logo.png' dst_path = 'data/temp/py-logo.png' download_file(url, dst_path)
За да посочите директорията на местоназначението и да запишете файла с името на URL файла, направете следното
def download_file_to_dir(url, dst_dir): download_file(url, os.path.join(dst_dir, os.path.basename(url))) dst_dir = 'data/temp' download_file_to_dir(url, dst_dir)
Той извлича името на файла от URL адреса с os.path.basename() и го обединява с директорията, зададена с os.path.join(), за да генерира пътя до местоназначението.
Следващите раздели описват частта от събирането на данни и частта от записването на данни като файл.
urllib.request.urlopen(): Отворен URL адрес
Използвайте urllib.request.urlopen(), за да отворите URL адреса и да изтеглите данните. Обърнете внимание, че urllib.urlopen() е изчерпана в Python 2.6 и по-ранни версии. urllib.request.urlretrieve() все още не е изчерпана, но може да бъде изчерпана в бъдеще.
За да избегнете спиране при възникване на изключение, улавяйте грешката с try и except.
В примера urllib.error е импортиран и само urllib.error.URLError е изрично уловен. Съобщението за грешка ще бъде показано, когато URL адресът на файла не съществува.
url_error = 'https://www.python.org/static/img/python-logo_xxx.png' download_file_to_dir(url_error, dst_dir) # HTTP Error 404: Not Found
Ако искате да улавяте и изключения (FileNotFoundError и др.) при локално записване, направете следното.(urllib.error.URLError, FileNotFoundError)
Възможно е също така да използвате библиотеката на трета страна Requests вместо стандартната библиотека urllib, за да отворите url адреса и да получите данните.
Записване на файл в двоичен режим в open()
Данните, които могат да бъдат получени с urllib.request.urlopen(), са низ от байтове (тип байтове).
Open() с mode='wb' като втори аргумент записва данните като двоични. w означава запис, а b – двоични.
По-прост пример за код
Вложени в себе си изявления могат да бъдат написани наведнъж, разделени със запетаи.
Използвайки това, можем да напишем следното.
def download_file(url, dst_path): try: with urllib.request.urlopen(url) as web_file, open(dst_path, 'wb') as local_file: local_file.write(web_file.read()) except urllib.error.URLError as e: print(e)
Изтегляне на ZIP файлове, PDF файлове и др.
Примерите досега са за изтегляне и запазване на файлове с изображения, но тъй като просто отваряме файл в уеб и го запазваме като локален файл, същите функции могат да се използват и за други видове файлове.
Можете да изтегляте и запазвате файлове, като посочите URL адреса.
url_zip = 'https://from-locas.com/sample_header.csv.zip' download_file_to_dir(url_zip, dst_dir) url_xlsx = 'https://from-locas/sample.xlsx' download_file_to_dir(url_xlsx, dst_dir) url_pdf = 'https://from-locas/sample1.pdf' download_file_to_dir(url_pdf, dst_dir)
Имайте предвид, че URL адресът, посочен в тази функция, трябва да е връзка към самия файл.
Например в случай на файл от хранилището на GitHub следният URL адрес има разширение pdf, но всъщност е html страница. Ако този URL адрес бъде посочен във функцията по-горе, ще бъде изтеглен html източникът.
- https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf
Връзката към файловата единица е следният URL адрес, който трябва да посочите, ако искате да изтеглите и запазите файла.
- https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf
Има и случаи, в които достъпът е ограничен по потребителски агент, препращач и т.н., което прави изтеглянето невъзможно. Не гарантираме, че всички файлове ще бъдат изтеглени.
Лесно е да използвате Заявки за промяна или добавяне на заглавия на заявки, като например потребителски агент.
Извлечете URL адреса на изображението в уеб страницата.
За да изтеглите всички изображения в дадена страница наведнъж, първо извлечете URL адресите на изображенията и създайте списък.
Ако номерът е последователен
Ако URL адресът на изображението, което искате да изтеглите, е просто последователен номер, това е лесно. Ако URL адресите са не само последователни числа, но и имат някаква закономерност, по-лесно е да се направи списък на URL адресите според правилата, отколкото да се изстъргват с Beautiful Soup (вж. по-долу).
Използвайте запис за разбиране на списък.
- Свързани статии:Използване на нотация за разбиране на списъци в Python
url_list = ['https://example.com/basedir/base_{:03}.jpg'.format(i) for i in range(5)] pprint.pprint(url_list) # ['https://example.com/basedir/base_000.jpg', # 'https://example.com/basedir/base_001.jpg', # 'https://example.com/basedir/base_002.jpg', # 'https://example.com/basedir/base_003.jpg', # 'https://example.com/basedir/base_004.jpg']
В горния пример {:03} се използва за 3-цифрено последователно число, попълнено с нула; {} се използва, когато не е необходимо попълване с нула, а {:05} се използва за 5-цифрено число вместо 3 цифри. За повече информация относно метода за форматиране на string str, вижте следната статия.
- Свързани статии:Преобразуване на формати в Python, формат (запълване с нули, експоненциален запис, шестнадесетична система и др.)
Освен това тук използваме pprint, за да направим изхода по-лесен за четене.
Екстракт с Красива супа
За масово извличане на URL адреси на изображения от уеб страници използвайте Beautiful Soup.
import os import time import urllib.error import urllib.request from bs4 import BeautifulSoup url = 'https://bg.from-locals.com/' ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) '\ 'AppleWebKit/537.36 (KHTML, like Gecko) '\ 'Chrome/55.0.2883.95 Safari/537.36 ' req = urllib.request.Request(url, headers={'User-Agent': ua}) html = urllib.request.urlopen(req) soup = BeautifulSoup(html, "html.parser") url_list = [img.get('data-src') for img in soup.find(class_='list').find_all('img')]
В примера се извлича URL адресът на миниатюрното изображение на този уебсайт.
Структурата варира в зависимост от уебстраницата, но основно се получава по следния начин.
- Получете списък с обекти на тага <img>, като посочите класа, id и т.н. на блока, съдържащ множество изображения, които искате да изтеглите.
soup.find(class_='list').find_all('img')
- Получете URL адреса на изображението от елемента src или data-src на тага <img>.
img.get('data-src')
Горният примерен код е само пример и не е гарантирано, че ще работи.
Пакетно изтегляне на множество изображения от списък с URL адреси
Ако имате списък с URL адреси, можете просто да го превърнете в цикъл for и да извикате функцията за изтегляне и записване на файла с първия показан URL адрес. Заради временния списък с URL адреси извикването на функцията download_image_dir() е коментирано тук.
download_dir = 'data/temp' sleep_time_sec = 1 for url in url_list: print(url) # download_file_dir(url, download_dir) time.sleep(sleep_time_sec) # https://example.com/basedir/base_000.jpg # https://example.com/basedir/base_001.jpg # https://example.com/basedir/base_002.jpg # https://example.com/basedir/base_003.jpg # https://example.com/basedir/base_004.jpg
За да не претоварвам сървъра, използвам time.sleep(), за да създам време за изчакване за всяко изтегляне на изображение. Единицата е в секунди, така че в примера по-горе е импортиран и използван модулът time.
Примерът е за файлове с изображения, но и други видове файлове могат да се изтеглят заедно, стига да са посочени в списъка.