python让你再也不为文章配图与素材发愁,让高清图片占满你的硬盘! #华为云·寻找黑马程序员#
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字“加群”,加入华为云线上技术讨论群;输入关键字“最新活动”,获取华为云最新特惠促销。华为云诸多技术大咖、特惠活动等你来撩!
电脑硬盘里的图片
收藏夹的照片(硬盘里的女神)看了又删,去年夏天后就没聊过天…很久前有这么一首歌很火,不知道大家听过没,只是括号里的歌词被改成了现在的样子。那么,你们以为我今晚要开车?NONONO…
每天做公众号,最愁的两件事,一是选题,二是公众号配图。不知道写什么,比写代码遇到坑更让人发愁。那么配图呢?配图的坑主要在于,选择的图首先要有美感或者和文章主题有所关联,最重要的是你选择的图必须是没有版权的。不然容易遭到投诉…网上推荐了很多免费的床图网站,我一直用的是pixabay
很多床图网站为什么选择它?一个是这个网站有百度云加速,虽然速度还是很卡(同样这里也是个坑,一会儿解释),而且预览图片时,不会添加网站的水印,你可以通过f12获取url的方式去下载图片,而无需注册后点进行下载,但是每次通过f12获取url的方式下载图片,有点太耗费时间了,所以今天就教大家通过python自动下载网站的所有图片,并巧妙实现网站的搜索引擎功能。
大坑解析
上面说到了,网站支持百度云加速,但同样的百度为了判断你是否为爬虫访问,会对浏览器进行监测。首次访问网站(有的运气好会访问几次后出现验证…),需要填写验证码确认非程序爬虫。之后才能正常使用。
但如果是拿requests进行url访问下载,怎么去破解?网上很多说什么js获取验证的,对于requests来说都不靠谱,当然你可以换成selenium前台模拟浏览器操作解析验证码然后去下载,先不说这验证码解析成果率多低,selenium的爬虫速度能和requests比?
我们该如何解决这个问题?我们先老老实实的输入验证码,然后看下面这张图:
http://pixabay.com网站存在7个cookie(显示9个是另外一个网站的…),然后一个一个查每个cookie的详细信息,连蒙带猜+验证,最后确定了,控制百度云的cookie有效期是通过cf_clearance时间来控制的,有效时长为一个半小时!
喜欢钻研的朋友可以考虑怎么修改这个时间,但对我来说,一个半小时够做太多东西了…
requests跳过百度云监测
知道了是由于cookie验证导致的访问异常,那我们该怎么做?通过headers添加cookie!
# -*- coding: utf-8 -*-
# @Author : 王翔
# @JianShu : 清风Python
# @Date : 2019/7/25 23:55
# @Software : PyCharm
# @version :Python 3.7.3
# @File : picture_download.py
import requests
from bs4 import BeautifulSoup
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"cookie":"__cfduid=dd2de4b5c79a4979c835e6925d31ad9741563739527; lang=zh; _ga=GA1.2.1567947853.1563739352; is_human=1; _gid=GA1.2.366594473.1564068124; cf_clearance=bb9e4a5a869c0a90e552c4a1f4e1dccc67dc021f-1564074082-1800-250; client_width=1903"
}
#
r =requests.get('https://pixabay.com/zh/images/search/',headers=headers)
print(r.text)
网站爬虫分析
再来个坑
刚才说了网站的图片是动态加载的,这个有什么坑呢?代码说话:
import requests
from bs4 import BeautifulSoup
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"cookie": "____cfduid=dd2de4b5c79a4979c835e6925d31ad9741563739527; lang=zh; _ga=GA1.2.1567947853.1563739352; is_human=1; _gid=GA1.2.366594473.1564068124; cf_clearance=2dfa6eddfa8309a53f97f2682d2fccf03ec6d4e2-1564078000-1800-250; client_width=1028"
}
#
r = requests.get('https://pixabay.com/zh/images/search/%E4%B9%A6/?pagi=4', headers=headers)
soup = BeautifulSoup(r.text, 'lxml')
items = soup.find("div", {"class": "search_results"}).find_all("div", {"class": "item"})
for item in items:
img = item.a.img
print(img.attrs)
我们会发现前十几张的url链接保存在srcset中,而之后的80+张图片他的url包裹在data-lazy-srcset中,后者的src也是默认的blank.gif的空白幕布,还么来得及把图片刷出来…
所以爬虫的时候我们需要小心了…如何快捷的判断到底使用哪个attr?这里用到一个python的 or方法,举个例子:
b = None or "abc"
b
>>> 'abc'
b = "abc" or None
b
>>> 'abc'
这样大家明白了吧,我们只需要 img.attrs.get(‘srcset’)即可。
只有你抠细节,才能成长!所以我问你,srcset放在or前还是data-lazy-srcset放在or前?再看一个例子:
b = "abc" or 0/0
b
>>> 'abc'
b = 0/0 or 'abc'
>>> Traceback (most recent call last):
File "<input>", line 1, in <module>
ZeroDivisionError: division by zero
当python遇到or运算时,如果第一个条件成立,那么直接返回数值,而不关注or后的表达式了!所以data-lazy-srcset有80+个,我们应该把它放在or的左边。够不够抠细节?细节决定成败!
小技巧1:指定内容检索
如何将我们的图片进行分类呢,网站的url也比较简单:
超过 8000 张关于“书”和“阅读”的免费图片 - Pixabay
search后的编码,通过from urllib.parse import quote即可获取,然后就是page的数字通过for循环匹配即可。
小技巧2:保存图片你索引
这里可是一个彩蛋了!大家都知道img一般都有一个alt的选项,即当图片显示不出来时,通过alt告诉大家这个图片是干嘛的!比如这些:
如果我们在保存图片的时候将图片名字中添加alt索引,之后我们通过windows自带的查找不就可以进行模拟网站的检索功能了么?是不是很鸡贼?哈哈…
小技巧3:获取高像素的图片
刚才我们看到了,默认的url是__340.jpg,像素比较低,但如果我们点击每个a标签的链接进入每个单张图的地址,会看到720p的中品质图片,那么要改链接一个一个解析?不用那么麻烦,这个网站的中品质图片link对比如下:
https://cdn.pixabay.com/photo/2019/07/22/09/02/landscape-4354610__340.jpg
https://cdn.pixabay.com/photo/2019/07/22/09/02/landscape-4354610_960_720.jpg
所以我们只需要将**__340替换为_960_720**即可获取高像素的图片了,聪明吧…
代码实现
提前强调一句,对于这种福利性的网站,大家还是下手轻一点,善待它吧!
# -*- coding: utf-8 -*-
# @Author : 王翔
# @JianShu : 清风Python
# @Date : 2019/7/26 02:55
# @Software : PyCharm
# @version :Python 3.7.3
# @File : picture_download.py
import os
import time
import requests
from bs4 import BeautifulSoup
from urllib.parse import quote, urljoin, urlsplit
import threading
class PictureDownload:
BaseUrl = "https://pixabay.com/zh/images/search/"
DefaultPages = 5
Path = os.path.dirname(os.path.abspath(__file__))
def __init__(self):
# cookie大家在使用的时候,记得替换...
self.headers = {
"cache-control":"Cache-control: private, max-age=0, no-cache",
"cf-ray":"4fc0bf640b4e20be-LAX",
"set-cookie":"lang=zh; expires=Sun, 22-Jul-2029 20:05:15 GMT; Max-Age=315360000; Path=/",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"cookie": "__cfduid=db4c7fedc0b42d0ba4df71f0a6bb61b001564084956; lang=zh; _ga=GA1.2.314030298.1564084752; _gid=GA1.2.2023032267.1564084752; is_human=1; client_width=1903; cf_clearance=65c758669b4c70b8d7300c06185fc16df3861533-1564085107-1800-250; _gat_UA-20223345-1=1"
}
self.url, self.download_path = self.set_basic()
def set_basic(self):
_url = urljoin(self.BaseUrl, quote(keyword))
_download_Path = os.path.join(self.Path, keyword)
if not os.path.exists(_download_Path):
os.mkdir(_download_Path)
return _url, _download_Path
def get_url(self):
for page in range(self.DefaultPages + 1):
parameter = {'pagi': page}
r = requests.get(self.url, params=parameter, headers=self.headers, timeout=10)
soup = BeautifulSoup(r.text, 'lxml')
items = soup.find("div", {"class": "search_results"}).find_all("div", {"class": "item"})
for item in items:
_img = item.a.img.attrs
link = _img.get("data-lazy-srcset") or _img.get("srcset")
alt = _img.get('alt')
t = threading.Thread(target=self.save_picture, args=(link, alt))
t.start()
time.sleep(0.2)
def save_picture(self, link, alt):
_url = link.split(' 1x')[0].replace('__340', '_960_720')
_file_name = os.path.join(self.download_path, alt + _url.split('/')[-1])
r = requests.get(_url, headers=self.headers, timeout=5)
try:
with open(_file_name, 'wb') as f:
f.write(r.content)
print("图片{}下载完成".format(_file_name))
except:
print("图片{}下载失败".format(_file_name))
if __name__ == '__main__':
keyword = str(input("请输入所需下载图片的关键字:"))
main = PictureDownload()
main.get_url()
来看看下载的效果,分别下载了图书、编程分类的图片,默认每个类型下载5页共1000张图片,:
由于部分图片链接失效,最终下载成功989张,总计内存165MB…
另外,刚才让保存alt的用处,现在就可以展示出来了,因为网站的图片检索也是通过关键字的,所以利用windows检索功能就实现了类似网站的检索操作:
是不是很炫酷?
The End
OK,今天的内容就到这里,如果觉得内容对你有所帮助,欢迎点击文章右下角的“在看”。
期待你关注我的公众号**清风Python**,如果觉得不错,希望能动动手指转发给你身边的朋友们。
来源:华为云社区征文 作者:清风Python
python让你再也不为文章配图与素材发愁,让高清图片占满你的硬盘! #华为云·寻找黑马程序员#的更多相关文章
- 使用jieba分析小说太古神王中,男主更爱谁?去文章中找答案吧!#华为云·寻找黑马程序员#
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- 使用Python开发小说下载器,不再为下载小说而发愁 #华为云·寻找黑马程序员#
需求分析 免费的小说网比较多,我看的比较多的是笔趣阁.这个网站基本收费的章节刚更新,它就能同步更新,简直不要太叼.既然要批量下载小说,肯定要分析这个网站了- 在搜索栏输入地址后,发送post请求获取数 ...
- 将Android手机打造成你的Python开发者桌面#华为云·寻找黑马程序员#
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- #华为云·寻找黑马程序员# 如何实现一个优雅的Python的Json序列化库
在Python的世界里,将一个对象以json格式进行序列化或反序列化一直是一个问题.Python标准库里面提供了json序列化的工具,我们可以简单的用json.dumps来将一个对象序列化.但是这种序 ...
- Python开发还在用virtualenv?不如了解下pipenv...#华为云·寻找黑马程序员#
又见 Kenneth Reitz 之前公众号写了一篇文章爬虫新宠requests_html 带你甄别2019虚假大学,其中主要是为了介绍模块**requests_html,这个模块的作者还开发了req ...
- Python正则表达式,看完这篇文章就够了...#华为云·寻找黑马程序员#【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- python最全学习资料:python基础进阶+人工智能+机器学习+神经网络(包括黑马程序员2017年12月python视频(百度云链接))
首先用数据说话,看看资料大小,达到675G 承诺:真实资料.不加密,获取资料请加QQ:122317653 包含内容:1.python基础+进阶+应用项目实战 2.神经网络算法+python应用 3.人 ...
- Python爬虫帮你打包下载所有抖音好听的背景音乐,还不快收藏一起听歌【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 【转】Python 代码批量抓取免费高清图片!
import requests from bs4 import BeautifulSoup import random import time from fake_useragent import U ...
随机推荐
- m99 然而并没有想出来标题!
这是放假回来的第一次考试,如同往常一样,我每逢放假回来第一次考试就会废掉,这次也不例外 这次不想粘成绩,因为实在是rp没了! 之前的几次都是别人在CE等等被lemon砍分,而我被lemon多测分. 但 ...
- Cpython和Jython的对比介绍
CPython 当我们从Python官方网站下载并安装好Python 3.x后,我们就直接获得了一个官方版本的解释器:CPython.这个解释器是用C语言开发的,所以叫CPython.在命令行下运行p ...
- Go 基础学习笔记 (5)| 数据类型说明与使用
在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...
- 基于typedef的用法详解【转】
也许新手用这个关键字不多,但它却是一个很有用的关键字,可以使代码模块化程度更好(即与其它代码的关联较少),在C++中还是实现Traits技术的基础,也是模板编程的基本语法之一. 若说变量定义是为变量命 ...
- python手册学习笔记1
笔记1 > http://www.pythondoc.com/pythontutorial3/controlflow.html 参数传递 Python中sys.argv的用法 调用解释器时,脚本 ...
- day7-集合
一.定义变量是为了吹处理状态的变化,定义变量名是为了获取变量值.字符串.数字.列表.元组.字典都是为了更好的描述变量的状态1.可变不可变:变量名不变时,里面内容是否可以变化# 可变:列表.字典.修改变 ...
- Jenkins + docker ,容器中跑docker服务
1. 宿主机:安装docker 2. 启动jenkins服务 https://jenkins.io/download/ Jenkins官网找自己需要的镜像版本号进行使用. docker run -it ...
- 领扣(LeetCode)Fizz Buzz 个人题解
写一个程序,输出从 1 到 n 数字的字符串表示. 1. 如果 n 是3的倍数,输出“Fizz”: 2. 如果 n 是5的倍数,输出“Buzz”: 3.如果 n 同时是3和5的倍数,输出 “FizzB ...
- [机器学习笔记]kNN进邻算法
K-近邻算法 一.算法概述 (1)采用测量不同特征值之间的距离方法进行分类 优点: 精度高.对异常值不敏感.无数据输入假定. 缺点: 计算复杂度高.空间复杂度高. (2)KNN模型的三个要素 kNN算 ...
- opencv MatchTemplate()模板匹配寻找最匹配部分
通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),可以获得越来越准确的匹配,然而,这同时也会以越来越大的计算量为代价.比较科学的方法是对所有这些方法多次测试实验,以便为自己的应用选择同时兼顾 ...