python让你再也不为文章配图与素材发愁,让高清图片占满你的硬盘!

怪毛病

最近写公众号写的染上了个怪毛病,不到12点根本不知道写啥。一过凌晨那简直是吃了大回复一般的文思泉涌。结果就是越熬夜越晚了.公众号是每天定时发的,简书上的发帖时间才是真正的睡前倒计时...然后,来看看都是几点睡的:


简书发文时间

为什么这么有精神?因为我武当王也改投了全真教,习得重阳真人一身武学典籍,本着不藏私的心态,在这里共享给大家,请叫我雷锋:

大道初修通九窍 九窍原在尾闾穴
先从涌泉脚底冲 涌泉冲过渐至膝
膝过徐徐至尾闾 泥丸顶上回旋急
秘语师传悟本初 来时无余去无踪
历年尘垢揩磨净 遍体灵明耀太虚
修真活记有何凭 心死群情今不生
精气充盈功行具 灵光照耀满神京
金锁关穿下鹊桥 重楼十二降宫室

电脑硬盘里的图片

收藏夹的照片(硬盘里的女神)看了又删,去年夏天后就没聊过天...很久前有这么一首歌很火,不知道大家听过没,只是括号里的歌词被改成了现在的样子。那么,你们以为我今晚要开车?NONONO...
每天做公众号,最愁的两件事,一是选题,二是公众号配图。不知道写什么,比写代码遇到坑更让人发愁。那么配图呢?配图的坑主要在于,选择的图首先要有美感或者和文章主题有所关联,最重要的是你选择的图必须是没有版权的。不然容易遭到投诉...网上推荐了很多免费的床图网站,我一直用的是pixabay

收藏夹

很多床图网站为什么选择它?一个是这个网站有百度云加速,虽然速度还是很卡(同样这里也是个坑,一会儿解释),而且预览图片时,不会添加网站的水印,你可以通过f12获取url的方式去下载图片,而无需注册后点进行下载,但是每次通过f12获取url的方式下载图片,有点太耗费时间了,所以今天就教大家通过python自动下载网站的所有图片,并巧妙实现网站的搜索引擎功能。

先来填个坑
大坑解析

上面说到了,网站支持百度云加速,但同样的百度为了判断你是否为爬虫访问,会对浏览器进行监测。首次访问网站(有的运气好会访问几次后出现验证...),需要填写验证码确认非程序爬虫。之后才能正常使用。

百度云监测

但如果是拿requests进行url访问下载,怎么去破解?网上很多说什么js获取验证的,对于requests来说都不靠谱,当然你可以换成selenium前台模拟浏览器操作解析验证码然后去下载,先不说这验证码解析成果率多低,selenium的爬虫速度能和requests比?
我们该如何解决这个问题?我们先老老实实的输入验证码,然后看下面这张图:
cookie有效时间

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解析的坑

我们会发现前十几张的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也比较简单:
https://pixabay.com/zh/images/search/%E4%B9%A6/?pagi=2
search后的编码,通过from urllib.parse import quote即可获取,然后就是page的数字通过for循环匹配即可。

小技巧2:保存图片你索引

这里可是一个彩蛋了!大家都知道img一般都有一个alt的选项,即当图片显示不出来时,通过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张图片,:


图片下载.gif

由于部分图片链接失效,最终下载成功989张,总计内存165MB....


下载效果

另外,刚才让保存alt的用处,现在就可以展示出来了,因为网站的图片检索也是通过关键字的,所以利用windows检索功能就实现了类似网站的检索操作:
检索功能

是不是很炫酷?

The End

OK,今天的内容就到这里,如果觉得内容对你有所帮助,欢迎点击文章右下角的“在看”。
期待你关注我的公众号清风Python,如果觉得不错,希望能动动手指转发给你身边的朋友们。
在之后的周一至五清晨7点10分,希望都能让清风Python的知识文章叫醒大家!谢谢……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容