爬虫——百度图片爬取

通用爬虫和聚焦爬虫
根据使用场景,网络爬虫可分为 通用爬虫 和 聚焦爬虫 两种。

通用网络爬虫:是捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分,是从互联网中搜集网页、采集信息,这些网页信息用于为搜索引擎建立索引从而提供支持,它决定着整个引擎系统的内容是否丰富,信息是否即时,因此其性能的优劣直接影响着搜索引擎的效果。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。

在这里插入图片描述

聚焦爬虫:是“面向特定主题需求”的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于,聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。即一般意义上的爬虫。
百度图片爬取
需求分析,至少要实现两个功能:一是搜索图片,二是自动下载
分析网页 http://image.baidu.com/search/index?tn=baiduimage&word=cat (注意:其中可以删除不用的参数,不影响页面的加载) 源代码,配合F12
编写正则表达式或者其他解析器代码
存储数据到本地
正式编写python爬虫代码
页面的分析是十分重要的,不同需求对应不同的URL,不同URL的源码显然是不一样的,所以掌握如何分析页面是成功爬虫的第一步。该页面的源码分析如下图所示:

在这里插入图片描述

import os
import re

import requests
from colorama import Fore


def download_image(url, keyword):
    """
    下载图片
    :param url: 百度图片的网址
    :return: Bool
    """
    #  1. 向服务器发起HTTP请求
    response = requests.get(url)
    #  2. 获取服务器端的响应信息
    #  响应信息: status_code, text, url
    data = response.text  # 获取页面源码
    #  3. 编写正则表达式,获取图片的网址
    # data = ...[{"ObjURL":"http:\/\/images.freeimages.com\/images\/large-previews\/3bc\/calico-cat-outside-1561133.jpg",....}]...
    # 需要获取到的是: http:\/\/images.freeimages.com\/images\/large-previews\/3bc\/calico-cat-outside-1561133.jpg
    # 正则的语法: .代表除了\n之外的任意字符, *代表前一个字符出现0次或者无数次. ?代表非贪婪模式
    pattern = r'"objURL":"(.*?)"'
    # 4. 根据正则表达式寻找符合条件的图片网址.
    image_urls = re.findall(pattern, data)
    # 5. 根据图片网址下载猫的图片到本地
    index = 1
    for image_url in image_urls:
        print(image_url)  # 'xxxx.jpg   xxxx.png'
        # response.text 返回 unicode 的文本信息, response.text 返回 bytes 类型的信息
        try:
            response = requests.get(image_url)  # 向每一个图片的url发起HTTP请求
        except Exception as e:
            print(Fore.RED + "[-] 下载失败: %s" % (image_url))
        else:
            old_image_filename = image_url.split('/')[-1]
            if old_image_filename:
            	# 获取图片的后缀
                image_format = old_image_filename.split('.')[-1]
                # 处理 url 为...jpeg?imageview&thumbnail=550x0 结尾(传参)的情况
                if '?' in image_format:
                    image_format = image_format.split('?')[0]
            else:
                image_format = 'jpg'
                
            # 生成图片的存储目录
            keyword = keyword.split(' ', '-')
            if not os.path.exists(keyword):
                os.mkdir(keyword)
            image_filename = os.path.join(keyword, str(index) + '.' + image_format)
			# 保存图片
            with open(image_filename, 'wb') as f:
                f.write(response.content)
                print(Fore.BLUE + "[+] 保存图片%s.jpg成功" % (index))
                index += 1


if __name__ == '__main__':
    keyword = input("请输入批量下载图片的关键字: ")
    url = 'http://image.baidu.com/search/index?tn=baiduimage&word=' + keyword
    print(Fore.BLUE + '[+] 正在请求网址: %s' % (url))
    download_image(url, keyword)

执行结果:
在这里插入图片描述
常见问题:

为什么只有30张图片,百度出来的不止30张
百度图片是响应式的,不断下拉会不断加载新的图片,也就是说浏览器中的页面是经过JS处理数据后生成的结果,涉及Ajax爬虫内容在此不做详细说明。
在搜索页面下点开的单个图片的 url 与程序中获取的 ObjURL 是不一致的
这可能是百度经过缓存处理的结果,每个图片本质上是“外网的”,非百度的,所以在程序中选择向真正存储图片的 url 发起 HTTP 请求。

发布了29 篇原创文章 · 获赞 0 · 访问量 891

猜你喜欢

转载自blog.csdn.net/weixin_45734982/article/details/105700489