使用python爬取图片(urllib.request.urlretrieve)

这是上课的时候老师留的作业,我在查证多方资料之后,终于做了出来,在此过程中我发现现在有很多这方面的代码讲解都是已经失效了的,故我将我的代码发不出来为自己存个档(完整代码在最下面)

  1. 首先要确定要爬取的网站

    现在https://image.baidu.com/这个百度图片网站不让爬了,使用这里面的ajax链接爬的话一直会返回Forbid spider access,搜了一下这是反爬的意思,但是我用requests.get爬取时将网页检查里的所有headers和params都加了进去,还是不让我爬,很烦,应该会有更好的解决办法,但是我是小菜鸡一个,我采用的方法是换一个网站爬,这里我爬的是https://unsplash.com/ 这个网站(因为我们老师给的实例是爬搜狗图片,淦,所以我只能选别的),是国外的,所以下载图片会有点慢
  2. 确定资源位置

    选好要爬取的网站后,接下来就要确定要爬取的资源的位置了,首先我们打开这个网址(我使用的是chrome浏览器)之后按F12打开检查台,先选择最上方的Network,再在下面一栏选择Fetch/XHR(ajax请求,XHR就是XMLHttpRequest)之后在左侧name那一栏里,可以找到我们的资源信息(现在还没有),接下来我们只需要往下滑动界面就可以,这个网页是动态显示的,向下滑的同时就可以持续的从数据库获取数据我们可以看到新增了两条信息,photo?per_page...这个就是我们需要的图片资源的请求,之后我们就可以在其中找到我们想要的信息,首先是headers,点击这个请求之后在右侧headers标签的最下方就有我们进行爬取是需要添加的请求头所有信息(我个人认为Referer和User-Agent这两个是必要的)我的代码里面添加了这个
    headers = {
                'Accept-Encoding': 'gzip, deflate, br',
                'Accept-Language': 'en-US',
                'Referer': 'https://unsplash.com/',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                              'Chrome/117.0.0.0 Safari/537.36'
            }

    因为我们老师要求的是爬取特定关键词的图片,所以现在就需要我看一下这个网站的搜索请求什么样子的,这里我简单的搜索一下“壁纸”这个关键词在我搜索之后出现的新请求里我们可以看到新加的这一行,这个就是我们之后需要爬取的关于搜索的url,之后我们切换到Payload标签下观察网址的参数情况它现在有两个参数,一个是query,一个是per_page,显而易见,query就是我们要搜索的关键词,我猜测per_page就是每页上面显示的图片数量,之后我们继续向下滑动使其动态从数据库获取数据,会发现新增了一个请求,它的参数列表如下发现它新增了一个参数叫page,由此我们可以推断出这个page应该就是第几页的意思。接下来网站的搜索关键词图片的显示方法我们就能够掌握了,就是通过query参数传递搜索内容,per_page是每页显示的图片数,page是第几页,之后的事情就是寻找每个图片的连接地址即可(我没有使用re表达式来查找图片链接的地址,因为不管什么方法都需要亲自去preview里面找图片对应的标签名称才可以,所以我直接自己将结构解开了一下),接下来我们还在这里点击Payload旁边的Preview标签会发现,这里显示一个results数据,里面是20条信息,这恰好也应对了我们之前推断的per_page参数是图片个数的猜想。之后打开其中一个图片观察到,在每个代号的里面都有一个urls数据,其中有很多条链接根据我山顶洞人般的英语推测,这个full应该是完整图片,raw是原图,small是小图,thumb是预览图,因为我之前说这是个国外的网站,所以我这次爬的是small图(我第一次爬的是full图,速度慢到我以为我的程序有bug)。将这些找完之后就可以愉快的写程序啦

  3. 代码部分

    首先是进行创建虚拟请求访问网址,这是爬虫最基础的东西,之后我们还需要三个参数,关键词、每页数量和页数。之后按照上面找好的位置进行每个图片链接的列表化
    # 图片网站网址
    # 通过网站ajax请求(XHR-XMLHttpRequest)中的Payload得知
    # 网站参数 query为关键词 per_page为每页的图片数量 page为第几页
    url = 'https://unsplash.com/napi/search/photos?query=' + category + '&per_page=' + str(n) + '&page=' + str(i)
    # 写网址标头模拟浏览器防止被禁止访问
    # 内容从浏览器检查网站ajax请求中Headers中取得
    # User-Agent, Referer对于程序模拟浏览器来说比较重要
    headers = {
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US',
        'Referer': 'https://unsplash.com/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                              'Chrome/117.0.0.0 Safari/537.36'
    }
    # 获取网页信息
    imgs = requests.get(url, headers)
    # 网页信息转为json数据
    jd = json.loads(imgs.text)
    # 通过阅读网站ajax请求中的preview标签内容
    # 确定网址的所在地为results->urls->full/raw/small
    # 将json数据解开一层
    jd = jd['results']
    # 网页中图片网址列表
    imgs_url = []
    # 保存每个图片的网址
    for j in jd:
        # 网址中各个图片的链接都在urls下
        j = j['urls']
        # 网站中有三种链接,full/raw/small
        # 取最小的图片链接下载(因为这是国外网站,图片太大下载很慢)
        imgs_url.append(j['small'])

    之后就是利用urlretrieve下载图片的过程,这里我的文件名称filepath是用参数的方式传递过来的

    # 利用urlretrieve循环下载图片
    for imgs_url in imgs_url:
        # 输出正在下载第几张图片
        print('*****' + str(m) + '.jpg *****' + '   Downloading...')
        # 使用urlretrieve下载图片,以m.jpg命名
        urllib.request.urlretrieve(imgs_url, filepath + str(m) + '.jpg')
        # 图片名称变量m递增
        m += 1

    之后再加亿些细节,程序就可以跑起来啦 ,下面是完整的代码:

    import json
    
    import requests
    
    import urllib.request
    
    
    def find_max_factor(n):
        """
        计算每页的图片数量
        :param n:需要下载的图片总数量
        :return:每页图片数量
        """
        # 从总数量的二分之一开始到2,倒序寻找最大因数
        for i in range(int(n / 2), 1, -1):
            # 若为因数则退出
            if n % i == 0:
                return i
        # 若寻找到2都没有最大因数,则其没有因数(为质数)
        return n
    
    
    def get_unsplash_imag(category, img_num, filepath):
        """
        根据信息从网页下载图片
        :param category:搜索关键词类型
        :param img_num:下载图片数量
        :param filepath:下载路径
        :return:null
        """
        # 图片名称递增变量
        m = 1
        # 算出每页的图片数量
        n = find_max_factor(img_num)
        # 计算需要多少页并循环下载每一页的图片
        for i in range(1, int(img_num / n) - 1):
            # 图片网站网址
            # 通过网站ajax请求(XHR-XMLHttpRequest)中的Payload得知
            # 网站参数 query为关键词 per_page为每页的图片数量 page为第几页
            url = 'https://unsplash.com/napi/search/photos?query=' + category + '&per_page=' + str(n) + '&page=' + str(i)
            # 写网址标头模拟浏览器防止被禁止访问
            # 内容从浏览器检查网站ajax请求中Headers中取得
            # User-Agent, Referer对于程序模拟浏览器来说比较重要
            headers = {
                'Accept-Encoding': 'gzip, deflate, br',
                'Accept-Language': 'en-US',
                'Referer': 'https://unsplash.com/',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                              'Chrome/117.0.0.0 Safari/537.36'
            }
            # 获取网页信息
            imgs = requests.get(url, headers)
            # 网页信息转为json数据
            jd = json.loads(imgs.text)
            # 通过阅读网站ajax请求中的preview标签内容
            # 确定网址的所在地为results->urls->full/raw/small
            # 将json数据解开一层
            jd = jd['results']
            # 网页中图片网址列表
            imgs_url = []
            # 保存每个图片的网址
            for j in jd:
                # 网址中各个图片的链接都在urls下
                j = j['urls']
                # 网站中有三种链接,full/raw/small
                # 取最小的图片链接下载(因为这是国外网站,图片太大下载很慢)
                imgs_url.append(j['small'])
            # 利用urlretrieve循环下载图片
            for imgs_url in imgs_url:
                # 输出正在下载第几张图片
                print('*****' + str(m) + '.jpg *****' + '   Downloading...')
                # 使用urlretrieve下载图片,以m.jpg命名
                urllib.request.urlretrieve(imgs_url, filepath + str(m) + '.jpg')
                # 图片名称变量m递增
                m += 1
        # 下载完成
        print('Download complete!')
    
    
    # 程序入口
    # 获取下载要求信息
    cate = input('请输入关键词:')
    num = eval(input('输入需要下载的图片数量:'))
    path = input('输入图片保存位置(输入已存在的文件夹):')
    # 处理文件路径问题
    if path[-1] != '/':
        path = path + '/'
    # 执行下载方法
    get_unsplash_imag(cate, int(num), path)
    

    这下心里的石头终于落地了,作业一交就完事,其实最好爬的还是百度图片,但是现在怎么也访问不到了,不知道是不是我自己的问题,希望这篇文章可以帮助到和我有一样问题的朋友们!

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新人不小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值