[编程经验] 我是如何半自动抓取素材公社图片的

时间:2022-05-08
本文章向大家介绍[编程经验] 我是如何半自动抓取素材公社图片的,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

网络爬虫是一件比较繁琐的事情,特别考验人的耐心。但又是非常令人着迷的一件事,因为当你从网络上爬到了自己的想要的数据,满满的成就感油然而生。但是我对爬虫掌握的并不好,所以我只能把我知道了,在这里做个分享,讲的不好,请见谅。记得当时找实习工作的时候,去面试某家公司的Python工程师,去了给了我一份标准的爬虫工程师的试卷,做完一脸懵逼啊!面试官都不想和我说话的感觉(./嫌弃.sh)。我觉得哈,面试者能力在差,你也不能表现出满眼的鄙视吧,这说明什么?!这种公司不去也罢!

简单介绍一下我对爬虫的理解。开始学习爬虫是被它强悍的功能所吸引,开始接触爬虫是很早以前听炼数成金的课程,讲的是R语言用Rcurl这个package来爬数据。Rcurl是怎么爬的?我也忘了,学过很久了,当时讲的也比较简单,主要还是爬虫整个原理。那时候对爬虫有了感性的概念,后来我从R转到了Python,所以就会接触一些Python爬虫的一些module,比如urllib,urllib2,scrapy,request等。在Python3里面把urllib和urllib2这两个合并成urllib了,并且很多API也变了。一个优秀的爬虫工程师,需要的能力有很多,因为爬虫涉及的知识面非常广,它涉及网络协议,HTML,javascript,正则表达式,编程语言,耐心等。下面我把最近爬取素材公社(http://www.tooopen.com/)网站上图片的方法,整个流程介绍一下,实战一下,你可能就对爬虫有了一个比较初步的认识了。

# -*- coding: utf-8 -*-

# 导入我们需要的urllib,re,os等模块,其中urllib主要用来爬数据,

# re是python的正则表达式解析的模块。

import urllib
import re
import os
import pprint
import sys
pp = pprint.PrettyPrinter()

这段可以把你想print的内容保存到文件里面,可用可不用。

# log_flie = open("images_url_list", "w")
# sys.stdout = log_flie

"""

定义我们的主要下载数据的函数,auto_download, 也可以写的简单点,主要就是urlretrieve()这个函数,但是为了我们的代码鲁棒性更强,防止爬虫过程中由

于网络问题而中断,所以这里定义了一个异常处理的情况。urlretrieve可以直接把一个连接包含的数据下载到本地文件夹。

"""

def auto_down(url, filename):
    try:
        image = urllib.urlretrieve(url, filename)
    except urllib.ContentTooShortError:
        print 'Network conditions is not good.Reloading.'
        image = auto_down(url, filename)
    return image

"""

接下来是一个建立url连接的函数,这个函数的目的是返回所有你想爬的网站连接,不过略显笨拙,但是能将就用。。url是?比如百度的链接地址,

https://www.baidu.com/,简单说就是一个网址,其中https表示网络协议。类似的还有http。这里我们打开素材公社的网站看一下。打开之后往下拉一点,找到图片素材,然点进去就看到左侧边有各种各样的图片,有风景,人物,动物,鲜花植物等等。我们以鲜花植物为例(因为我还做不到整站爬数据,囧!)

"""

然后看到就是这样的,然后我们依次打开玫瑰花,荷花,向日葵以及后面的每一种,都打开。然后看下他的网址。

http://www.tooopen.com/img/856_857.aspx

http://www.tooopen.com/img/856_858.aspx

http://www.tooopen.com/img/856_860.aspx

http://www.tooopen.com/img/856_861.aspx

http://www.tooopen.com/img/856_862.aspx

http://www.tooopen.com/img/856_864.aspx

http://www.tooopen.com/img/856_866.aspx

http://www.tooopen.com/img/856_868.aspx

http://www.tooopen.com/img/856_412.aspx

http://www.tooopen.com/img/856_413.aspx

http://www.tooopen.com/img/856_414.aspx

http://www.tooopen.com/img/856_577.aspx

然后我们观察一下这些链接,发现一个规律就是其中变化的部分就只有856_后面的数字,不同的数字就会跳转到不同植物类别, 577, 414, 413, 412, 868, 866, 864, 862, 861, 860, 858, 857.除了这些数字不同以外,其他地址都是相同的。然后我们打开玫瑰花那一类,拉到最下面看一下

然后把下面的每一页都打开看看,我们又会发现一个规律。

http://www.tooopen.com/img/856_857_1_1.aspx

http://www.tooopen.com/img/856_857_1_2.aspx

http://www.tooopen.com/img/856_857_1_3.aspx

http://www.tooopen.com/img/856_857_1_4.aspx

856_857_1_{},除了大括号里面的,其他的都没变。你也可以再地址栏里面直接改变一下其中的数字,就会跳转到相应的界面,但是这个页面是有限的,而且这里要注意每一种鲜花类别的页面数量是不一样的,所以我们如果要一次遍历所有的页面,只能取其中页面数量最少的那个类别,make_url_list这个函数中deptp就代表页面数量。

def make_url_list(depth):
    # 首先定义一个空列表,这里将要放的是我们最终返回的url。
    urls_list_all = []
    # depth表示深度
    for i in range(depth):
        # num_list = [312, 880, 311, 314, 315, 316, 399, 313, 881, 882]
        # num_list = [282, 876, 877, 878, 879, 292, 302, 889, 281, 395, 396]
        num_list = [577, 414, 413, 412, 868, 866, 864, 862, 861, 860, 858, 857]
        for num in num_list:
            # urls_list = "http://www.tooopen.com/img/88_{}_{}.aspx".format(num, i)
            urls_list = " http://www.tooopen.com/img/88
                               _{}_1_{}.aspx".format(num, i)
            urls_list_all.append(urls_list)
    return urls_list_all

最后一个函数的目的是为了解析图片链接地址,我们这里在网站上看一下。(这样说感觉好别扭,囧!)这里推荐使用谷歌浏览器,没有为什么,就是好用!打开之后,按F12,或者鼠标右键点检查。右侧(也可能在下面)就会就会出现一大堆乱七八糟的东西,

仔细看一下这些怪文(Html)就会在其中发现 src="http://img07.tooopen.com/images/20170315/tooopen_sl_201917535673.jpg"

这个就是我们最终想下载的图片的链接,接下来的这个函数的目的就是为了找出这个链接。

接下来我们定义函数make_image_list,来找到这些链接。

def make_image_list(urls_list):
    # 最后返回的图片链接地址
    imglist_all = []
    for urls in urls_list:
        try:
            page = urllib.urlopen(urls)
            html = page.read()
            # 正则表达式
            reg = r'src="(.+?.jpg)"'
            imgre = re.compile(reg)
            imglist = re.findall(imgre, html)
            imglist_all.append(imglist)
        except NotImplementedError:
            print "error"
    return imglist_all
"""
urls_list = make_url_list(11)也可以替换为
for i in range(depth):
    urls_list = " http://www.tooopen.
    com/img/88_577_1_{}.aspx".format(i)
# 或者也可以这样建立url地址,这样深度可以设置的更大一点。

"""
if __name__ == "__main__":
    # 建立url地址,深度设为11,
    urls_list = make_url_list(11)
    # 调用make_image_list建立图片链接地址
    images_url_list = make_image_list(urls_list)
    counter = 1
    # 遍历所有的图片链接
    for image_url in images_url_list:
        if image_url is None:
            continue
        for image in image_url:
            # print(" url ", image)
            # 新建下载图片保存的地址,主要这里如果
            # 每次下载的鲜花类型不同,注意修改文件
            # 夹的名字,防止下载数据被覆盖。
            save_path = "./beautiful_girls/"
            # 如果不存在,则新建文件夹
            if not os.path.exists(save_path):
                os.makedirs(save_path)
            target = os.path.join(save_path, '%06d.jpg' % counter)
            # 调用之前的auto_down函数,开始尽情的下载图片
            download_image = auto_down(image, target)
            counter += 1

最后这里也可以加一点打印image_url的信息,这样可以看一下,爬虫运行的情况。

比如这样:

if counter % 10 == 0:

pp.pprint("This is the {} download images".format(counter))

pp.pprint("The download image url is {}".format(image))

pp.pprint("The download image name is {}".format(target))

最后我们总结一下流程:

  1. 首先找到你爬虫需要找到的url
  2. 然后找到这些url的子链接
  3. 最后找到所有连接中包含图片下载的链接,并使用正则表达式解析地址。
  4. 下载到本地。

当然今天这个只是一个比较简单的爬虫,没有模拟登陆,大规模分布式等等高级的内容,但是作为入门,我觉得还是值得大家去学习的。玩的开心喽!

最后晒一下我的成果,截止到现在,我们的小爬虫,已经搬运回来上万张图片了。

本文为作者原创,如有雷同,必然是别人抄我的。