获取素材图无忧,Pixabay图库网Python多线程采集下载
时间:2022-07-22
本文章向大家介绍获取素材图无忧,Pixabay图库网Python多线程采集下载,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
图片素材想必是不少人都在寻找的内容,随着版权意识的加深,可供免费使用的图片素材可不是那么好找的哦,不过还是有不少国外知名素材网站可供我们使用,而且国内访问也是比较快,同时支持中文,感谢网站制作及素材分享者们!
下面来以一个大部分人都熟悉的图库网站,Pixabay,为例,使用Python多线程采集下载美女图片素材。
Pixabay是全球知名的图库网站及充满活力的创意社区,拥有上百万张免费正版高清照片素材,涵盖风景、人物、动态、静物等多种分类,你可以在任何地方使用Pixabay图库中的素材,无惧版权风险。
目标网址:
https://pixabay.com/zh/images/search/美女/
同样的,还有一个推荐网站,也是非常出名的,设计小哥哥强烈推荐的:
https://www.pexels.com/zh-tw/
大家可以自行练手尝试!
关键,免费,无需为版权问题所困扰!
抓取效果:
多线程运行效果:
几个关键点:
1.字符串utf-8编码
网址中中文转换为utf-8的编码还是比较常见的,这里使用 urllib.parse 转码
import urllib.parse
category="美女"
category=urllib.parse.quote(category) #转换utf-8编码
print(category)
2.使用request.urlretrieve下载图片卡机的问题解决
下载文件出现urllib.ContentTooShortError且重新下载文件会存在用时过长的问题,而且往往会尝试好几次,甚至十几次,偶尔会陷入死循环,这种情况是非常不理想的。
为此,笔者利用socket模块,使得每次重新下载的时间变短,且避免陷入死循环,从而提高运行效率。
import socket
import urllib.request
#设置超时时间为30s
socket.setdefaulttimeout(30)
#解决下载不完全问题且避免陷入死循环
try:
urllib.request.urlretrieve(url,image_name)
except socket.timeout:
count = 1
while count <= 5:
try:
urllib.request.urlretrieve(url,image_name)
break
except socket.timeout:
err_info = 'Reloading for %d time'%count if count == 1 else 'Reloading for %d times'%count
print(err_info)
count += 1
if count > 5:
print("downloading picture fialed!")
#来源:本文为CSDN博主「山阴少年」
3.Python zip() 函数的用法
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped) # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
附单线程版本:
#https://pixabay.com 图片抓取
import requests
from fake_useragent import UserAgent
import urllib.parse
from urllib import request
from lxml import etree
import re,os,time
def parse_page(url):
opener = request.build_opener()
opener.addheaders = [('User-Agent',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
request.install_opener(opener)
ua=UserAgent()
headers={'UserAgent':ua.random}
response=requests.get(url,headers=headers,timeout=10).content.decode('utf-8')
time.sleep(2)
print(response)
html=etree.HTML(response)
imgs=html.xpath('//div[@class="flex_grid credits search_results"]/div[@class="item"]/a/img/@data-lazy-srcset')
alts=html.xpath('//div[@class="flex_grid credits search_results"]/div[@class="item"]/a/img/@alt')
print(imgs)
print(alts)
for img,alt in zip(imgs,alts):
img_url=re.findall('1x, (.*?) 2x', img)[0]
suffix = os.path.splitext(img_url)[1] # 获取后缀名
img_name='%s%s'%(alt.replace(',','_'),suffix)
print(img_url,img_name)
'''
try:
request.urlretrieve(img_url, '%s%s'%('pixabay/',img_name))
print(">>> 图片下载完成!")
time.sleep(1)
except Exception as e:
print(f'下载图片失败,错误代码:{e}')'''
try:
r = requests.get(img_url, headers=headers,timeout=10)
time.sleep(1)
with open('%s%s'%('pixabay/',img_name), 'wb') as f:
f.write(r.content)
print("图片下载完成!")
except Exception as e:
print(f'下载图片失败,错误代码:{e}')
def main():
category="美女"
category=urllib.parse.quote(category) #转换utf-8编码
print(category)
for i in range(1,3):
print(">>> 正在抓取第%d页..." % i)
url="https://pixabay.com/zh/images/search/%s/?pagi=%d" %(category,i)
print(url)
parse_page(url)
if __name__=='__main__':
main()
附多线程版本:
经典的生产者与消费者模式
注意,经过测试,当分页小于3时候,线程运行会出现问题,与循环的控制设置相关。
#https://pixabay.com 图片抓取
import requests
from fake_useragent import UserAgent
import urllib.parse
from urllib import request
from lxml import etree
import re,os,time
import threading
from queue import Queue
#生产者模式
class Producer(threading.Thread):
def __init__(self,page_queue,img_queue,*args,**kwargs):
super(Producer,self).__init__(*args,**kwargs)
self.page_queue=page_queue
self.img_queue=img_queue
def run(self):
while True:
if self.page_queue.empty():
break
url=self.page_queue.get()
self.parse_page(url)
def parse_page(self,url):
ua=UserAgent()
headers={'UserAgent':ua.random}
response=requests.get(url,headers=headers,timeout=10).content.decode('utf-8')
time.sleep(2)
html=etree.HTML(response)
imgs=html.xpath('//div[@class="flex_grid credits search_results"]/div[@class="item"]/a/img/@data-lazy-srcset')
alts=html.xpath('//div[@class="flex_grid credits search_results"]/div[@class="item"]/a/img/@alt')
print(imgs)
print(alts)
for img,alt in zip(imgs,alts):
img_url=re.findall('1x, (.*?) 2x', img)[0]
suffix = os.path.splitext(img_url)[1] # 获取后缀名
img_name='%s%s'%(alt.replace(',','_'),suffix)
self.img_queue.put((img_url,img_name))
#消费者模式
class Consumer(threading.Thread):
def __init__(self, page_queue, img_queue, *args, **kwargs):
super(Consumer, self).__init__(*args, **kwargs)
self.page_queue = page_queue
self.img_queue = img_queue
def run(self):
ua = UserAgent()
headers = {'UserAgent': ua.random}
while True:
if self.img_queue.empty() and self.page_queue.empty():
break
img_url,img_name=self.img_queue.get()
print(img_url,img_name)
r = requests.get(img_url, headers=headers,timeout=10)
time.sleep(2)
with open('%s%s'%('pixabay/',img_name), 'wb') as f:
f.write(r.content)
print("图片下载完成!")
def main():
category="美女"
category=urllib.parse.quote(category) #转换utf-8编码
print(category)
page_queue=Queue(100)
img_queue=Queue(1000)
for i in range(1,51):
print(">>> 正在抓取第%d页..." % i)
url="https://pixabay.com/zh/images/search/%s/?pagi=%d" %(category,i)
print(url)
page_queue.put(url)
for x in range(5):
t=Producer(page_queue,img_queue)
t.start()
for x in range(5):
t=Consumer(page_queue,img_queue)
t.start()
if __name__=='__main__':
main()
- 小窗播放视频的原理和实现(上)
- 一种Android App在Native层动态加载so库的方案
- java的双缓冲技术
- application之OnLowMemory()和 OnTrimMemory(level)讲解
- React Native组件(一)组件的生命周期
- Spring Cloud构建微服务架构:服务消费(基础)【Dalston版】
- Android解析ClassLoader(一)Java中的ClassLoader
- Android学习笔记(一)之仿正点闹钟时间齿轮滑动的效果
- Android解析WindowManager(三)Window的添加过程
- Spring Cloud构建微服务架构:服务消费(Ribbon)【Dalston版】
- Android解析WindowManager(一)WindowManager体系
- ios9 http请求失败的问题
- Android内存优化(六)LeakCanary使用详解
- Spring Cloud构建微服务架构:服务消费(Feign)【Dalston版】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android 在一个APP里打开另一个APP
- Android 自定义加载动画Dialog弹窗
- Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化
- Android 天气APP(十)继续优化、下拉刷新页面天气数据
- Activity 活动跳转(Java&Kotlin)
- Android 天气APP(九)细节优化、必应每日一图
- Android CheckBox修改选中颜色并去除选中时的水波纹效果
- 绘制带回归线的散点图
- Java&Android像素px、dip转换工具类
- Android WIFI是否连接,网络状态监测工具类
- Kotlin学习日志(五)类与对象
- Android 应用横屏运行
- Android 修改EditView输入框的光标颜色
- Android控件显示、隐藏时,增加动画效果
- Android 自定义样式Shape