Este artigo falará sobre COMO BAIXAR ARQUIVOS DE IMAGEM COM PYTHON RoboBrowser para baixar em massa de arquivos de imagem do Pexels , um site que oferece downloads gratuitos. Se você está procurando trabalhar com imagens, ou deseja construir um conjunto de treinamento para um classificador de imagens com Python, este post irá ajudá-lo a fazer isso.
Na primeira parte do código, carregaremos a classe RoboBrowser do pacote robobrowser, criaremos um objeto de navegador que atua como um navegador da web e navegaremos até o site da Pexels .
# load the RoboBrowser class from robobrowser
from robobrowser import RoboBrowser
# define base site
base = "https://www.pexels.com/"
# create browser object,
# which serves as an invisible web browser
browser = RoboBrowser()
# navigate to pexels.com
browser.open(base)
Se você realmente for ao site, verá que há uma caixa de pesquisa. Podemos identificar este formulário de pesquisa usando o método get_form . Assim que tivermos este formulário, podemos verificar quais campos ele contém imprimindo o atributo fields .
form = browser.get_form()
print(form.fields)
Imprimir os campos mostra-nos que o nome do campo de pesquisa associado à caixa de pesquisa é “s”. Isso significa que se quisermos digitar algo programaticamente na caixa de pesquisa, precisamos definir o valor desse campo para nossa entrada de pesquisa. Assim, se quisermos pesquisar imagens de “água”, podemos fazê-lo da seguinte forma:
# set search input to water
form["s"] = "water"
# submit form
browser.submit_form(form)
Depois de enviar a caixa de pesquisa, podemos ver qual é o nosso URL atual verificando o atributo url .
print(browser.url)
A seguir, vamos examinar os links na página de resultados.
# get links on page
links = browser.get_links()
# get the URL of each page by scraping the href attribute
# of each link
urls = [link.get("href") for link in links]
# filter out any URLs from links without href attributes
# these appear as Python's special NoneType
urls = [url for url in urls if url is not None]
Agora que temos os URLs na página, vamos filtrá-los apenas para aqueles que mostram as imagens do resultado da pesquisa na página. Podemos fazer isso procurando onde “/ photo /” aparece em cada URL.
# filter to what we need -- photo URLs
photos = [url for url in urls if '/photo/' in url]
# get photo link objects
photo_links = [link for link in links if link.get("href") in photos]
Para o nosso primeiro exemplo, vamos clicar no primeiro link da foto (0º link indexado por Python) usando o método follow_link .
browser.follow_link(photo_links[0])
Em seguida, queremos encontrar o link na tela que diz “Download grátis”. Isso pode ser feito usando o método get_link do navegador. Tudo o que precisamos fazer é passar qualquer texto no link que estamos procurando, ou seja, “Download grátis” neste caso.
# get the download link
download_link = browser.get_link("Free Download")
# hit the download link
browser.open(download_link.get("href"))
Depois de clicar no link, podemos gravar os dados do arquivo no disco, usando browser.response.content
# get file name of picture from URL
file_name = photo[0].split("-")[-2]
with open(file_name + '.jpeg', "wb") as image_file:
image_file.write(browser.response.content)
Suponha que desejamos baixar todas as imagens da página de resultados. Podemos ajustar nosso código acima assim:
# download every image on the first screen of results:
for url in photos:
full_url = "https://pexels.com" + url
try:
browser.open(full_url)
download_link = browser.get_link("Free Download")
browser.open(download_link.get("href"))
file_name = url.split("/")[-2] + '.jpg'
with open(file_name, "wb") as image_file:
image_file.write(browser.response.content)
except Exception:
pass
Em vez de apenas baixar as imagens para uma consulta de pesquisa específica, podemos modificar nosso código acima para criar uma função generalizada, que baixará as imagens do resultado da pesquisa associadas a qualquer entrada que escolhermos.
Generalized function
def download_search_results(search_query):
browser.open(base)
form = browser.get_form()
form['s'] = search_query
browser.submit_form(form)
links = browser.get_links()
urls = [link.get("href") for link in links]
urls = [url for url in urls if url is not None]
# filter to what we need -- photos
photos = [url for url in urls if '/photo/' in url]
for url in photos:
full_url = "https://pexels.com" + url
try:
browser.open(full_url)
download_link = browser.get_link("Free Download")
browser.open(download_link.get("href"))
file_name = url.split("/")[-2] + '.jpg'
with open(file_name, "wb") as image_file:
image_file.write(browser.response.content)
except Exception:
pass
Então, podemos chamar nossa função assim:
download_search_results("water")
download_search_results("river")
download_search_results("lake")
Como mencionado anteriormente, usar o RoboBrowser para baixar imagens do Pexels também pode ser muito útil se você estiver procurando construir seu próprio classificador de imagens e precisar coletar imagens para um conjunto de treinamento. Por exemplo, se você quiser construir um classificador que preveja se uma imagem contém um cachorro ou não, você pode raspar Pexels com nossa função acima para obter imagens de treinamento, como esta:
download_search_results("dog")
Até agora, nosso código tem uma desvantagem principal – nossa função atualmente apenas puxa o valor de uma página de resultados. Se você deseja obter páginas adicionais, precisamos ajustar o URL de pesquisa. Por exemplo, para obter a segunda página de imagens de cães, precisamos acessar https://www.pexels.com/search/dog/?page=2 . Se quisermos obter páginas adicionais, precisamos alterar o código de nossa função para atingir esses URLS sequenciais -? Page = 2,? Page = 3, … até que tenhamos todas as imagens baixadas ou tenhamos alcançado uma determinada página limite. Considerando que pode haver milhares de imagens associadas a uma consulta de pesquisa específica, você pode definir um limite para o número de páginas de resultados de pesquisa que acessa.
Generalized function – download all page results up to a limit
def download_all_search_results(search_query, MAX_PAGE_INDEX = 30):
browser.open(base)
form = browser.get_form()
form['s'] = search_query
browser.submit_form(form)
search_url = browser.url # new URL
# create page index counter
page_index = 1
# define temporary holder for the photo links
photos = [None]
# set limit on page index
# loop will break before MAX_PAGE_INDEX if there are less page results
while photos != [] and page_index <= MAX_PAGE_INDEX:
browser.open(search_url + "?page=" + str(page_index))
links = browser.get_links()
urls = [link.get("href") for link in links]
urls = [url for url in urls if url is not None]
# filter to what we need -- photos
photos = [url for url in urls if '/photo/' in url]
if photos == []:
break
for url in photos:
full_url = "https://pexels.com" + url
try:
browser.open(full_url)
download_link = browser.get_link("Free Download")
browser.open(download_link.get("href"), stream = True)
file_name = url.split("/")[-2] + '.jpg'
with open(file_name, "wb") as image_file:
image_file.write(browser.response.content)
except Exception:
pass
print("page index ==> " + str(page_index))
page_index += 1
Agora podemos chamar nossa função semelhante a acima:
# download all the images from the first 30 pages
# of results for 'dog'
download_all_search_results("dog")
# Or -- just get first 10 pages of results
download_all_search_results("dog", 10)
Você também pode limitar o número de downloads diretamente, ou seja, definir um limite de 100, 200, 300 ou um número “X” de imagens que deseja baixar.
Veja mais artigos sobre Python neste site aqui.