通过关键字从百度中爬取相匹配图片,可以爬取多种也可以爬取一种图片

通过re、requests、urlib、BeautifulSoup、os模块实现从百度下载指定类别图片。包含代码逐行解析。

python 复制代码
import re
# 进行http请求的第三方库
import requests
from urllib import error
# 解析HTML和XML文档的库
from bs4 import BeautifulSoup
import os
 
num = 0
numPi = 0
file = ''
List = []
 
def makefile(word):
    file = word + '文件'
    file_na = os.path.exists(file)
    if file_na == 1:
        print('该文件已存在,请重新输入')
        file = input('请建立一个存储图片的文件夹,输入文件夹名称即可: ')
        os.mkdir(file)
    else:
        os.mkdir(file)
    return file

 
# 根据地址去查找 对应的图片的信息
# 获取网页中图片URL函数
# url是目标网页的URL,A是用来发送http请求的类,通常是Request对象
def Find(url, A):
    global List  # 保存信息的列表,保存获取图片的URL
    t = 0           # 请求时间
    i = 1           # 请求次数
    s = 0           # 当前获取到的图片总数
    while t < 60000:
        # 时间戳 不间断刷新访问网址
        # 目标网页的URL与当前时间戳t拼接,形成一个新的url
        Url = url + str(t)
        try:
            # get获取数据,访问拼接后的url
            Result = A.get(Url, timeout=7, allow_redirects=False)
        # 捕获所有请求超时、URL错误等异常
        except BaseException:
            # 每一页有60张图片所以
            t = t + 60
            continue
        else:
            # 拿到网站的数据,捕获到的网页内容给result变量
            result = Result.text
            # 找到图片url,使用正则表达式从网页内容中提取图片url,并将结果赋值给pic_url变量
            pic_url = re.findall('"objURL":"(.*?)",', result, re.S)
            # 图片总数
            # 提取到的图片url数量加到s变量上
            s += len(pic_url)
            # 如果提取到的图片URL数量为 0,表示网页中没有图片,跳出循环
            if len(pic_url) == 0:
                break
            else:
                # 将提取到的图片 URL 添加到 List 列表中。
                List.append(pic_url)
                #  将时间戳 t 增加 60 秒,然后继续循环
                t = t + 60
    return s
 
 
# 记录相关数据
def recommend(url):
    Re = []
    try:
        # 向网页发送一个请求并返回响应
        html = requests.get(url, allow_redirects=False)
    except error.HTTPError as e:
        return
    else:
        html.encoding = 'utf-8'
        # html文件解析,解析响应的文件内容,html.text 是 HTML 文档的源代码,
        # 'html.parser' 是解析器,用于指定如何解析 HTML 文档
        bsObj = BeautifulSoup(html.text, 'html.parser')
        # 找到页面中id为topsRS的div元素
        div = bsObj.find('div', id='topRS')
        # 从该div元素中找到所有a的标签,并提取其中文本内容
        if div is not None:
            listA = div.findAll('a')
            for i in listA:
                if i is not None:
                    Re.append(i.get_text())
        return Re
 
 
# 下载图片
def dowmloadPicture(html, keyword):
    # 记录已经下载的图片数量
    global num
    # 找到图片url
    # 正则表达式从 HTML 中提取所有包含图片 URL 的字符串。re.S 参数表示使正则表达式对大小写不敏感。
    # (.*?):这是一个捕获组,用于匹配括号内的内容。点号(.)表示匹配任意字符,*? 表示匹配任意数量的字符,匹配一个引号、匹配一个逗号
    # 查找 html 中所有以 "objURL" 开头,并且以双引号和逗号结尾的字符串,并将这些字符串作为匹配结果返回
    pic_url = re.findall('"objURL":"(.*?)",', html, re.S)
    print('找到:' + keyword + '的图片,开始下载....')
    # 遍历图片的url
    for each in pic_url:
        print('正在下载第' + str(num + 1) + '张图片,图片地址:' + str(each))
        # 处理异常,主要处理图片下载失败的情况
        try:
            if each is not None:
                # 请问时间不能超过7s
                pic = requests.get(each, timeout=7)
            else:
                continue
        except BaseException:
            print('错误,当前图片无法下载')
            continue
        else:
            # 构建图片保存路径
            string = file + r'\\' + str(num) + '.jpg'
            # 以二进制写入模式打开新建文件
            fp = open(string, 'wb')
            # 将下载的图片内容写入文件
            fp.write(pic.content)
            # 关闭文件
            fp.close()
            # 已经下载一张图片加1
            num += 1
        # 检查是否已经下载所有需要下载的图片
        if num >= numPi:
            return
 
 
if __name__ == '__main__':  # 主函数入口
    # 模拟浏览器 请求数据 伪装成浏览器向网页提取服务,有的网站识别出你是python就会拒绝
    # 请求头是在发送http请求时,由客户端向服务器发送一些元数据,描述请求的特性和客户端的能力
    # 请求头通常由浏览器自动设置,也可由程序(python)脚本手动设置
    # 返回的文档语言,客户端和服务端建立一个持久的连接,客户端的身份,客户端是否愿意升级不安全的请求
    headers = {
        'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Connection': 'keep-alive',
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
        'Upgrade-Insecure-Requests': '1'
    }
 
    # 创建一个请求的会话
    A = requests.Session()
    # 设置头部信息
    A.headers = headers
    choice = int(input("请问需要搜索多类图片还是单类图片?如果是单类请输入0,如果是多类请输入1:"))
    if choice == int(0):
        word = input("输入要搜索的关键词:")
        numPi = int(input('输入要下载的数量:'))
        # 拼接路径
        url = 'https://image.baidu.com/search/flip?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs1&word=' + word
 
        # 根据路径去查找
        total = Find(url, A)
        # 记录相关推荐图片
        Recommend = recommend(url)
        print('经过检测%s类图片共有%d张' % (word, total))
        file = makefile(word)

        t = 0
        tmp = url
    
        while t < numPi:
            try:
                url = tmp + str(t)
                result = requests.get(url, timeout=10)
                print(url)
            except error.HTTPError as e:
                print('网络错误,请调整网络后重试')
                t = t + 60
            else:
                dowmloadPicture(result.text, word)
                t = t + 60

    else: 
        tm = int(input('请输入每类图片的下载数量 '))
        numPi = tm
        line_list = []
        with open('./name.txt', encoding='utf-8') as file:
            line_list = [k.strip() for k in file.readlines()]  # 用 strip()移除末尾的空格
        for word in line_list:
            #url = 'https://image.baidu.com/search/flip?ct=201326592&cl=2&st=-1&lm=-1&nc=1&ie=utf-8&tn=baiduimage&ipn=r&rps=1&pv=&fm=rs1&word=' + word
            url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='
            tot = Find(url,A)
            Recommend = recommend(url)  # 记录相关推荐
            print('经过检测%s类图片共有%d张' % (word, tot))
            file = makefile(word)
            
            t = 0
            tmp = url
            while t < numPi:
                try:
                    url = tmp + str(t)
                    result = A.get(url, timeout=10, allow_redirects=False)
                    print(url)
                except error.HTTPError as e:
                    print('网络错误,请调整网络后重试')
                    t = t + 60
                else:
                    dowmloadPicture(result.text, word)
                    t = t + 60

            numPi = numPi + tm
        
相关推荐
databook3 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar4 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780514 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_4 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机11 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机12 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i12 小时前
drf初步梳理
python·django
每日AI新事件12 小时前
python的异步函数
python