基于 selenium 实现网站图片采集

写在前面


  • 有小伙伴选题,简单整理
  • 理解不足小伙伴帮忙指正

对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》


采集原理

一般情况下可以通过 selenium 来批量获取图片,定位元素,获取URL ,逻辑相对简单:

部分页面可能存在 翻页,懒加载的情况,一般使用 selenium 基本可以解决(下文 Demo 只涉及了 懒加载场景 )

采集图片实质上是采集图片对应的uri ,图片 URI 一般有三种:

  • 一种为返回可预览的图片,报文类型为 image/jpeg,是一个 JPEG 图像文件,一般uri 后缀为图片名称后缀
  • 一种为返回可以直接下载的图片,报文类型为 binary/octet-stream,是一种二进制数据的 MIME 类型。
  • 最后一种为直接返回 b64 编码的方式,

所以实际编码中需要考虑这三种情况,对于 b64 编码可以直接保存,对应 其他两两种 uri ,考虑转化字节或者 b64 编码下载

需要注意的问题

  1. selenium 的版本问题,3 版本的和 4 版本 部分 方法差距较大,在实际编码中需要注意
  2. 图片版权问题,是否允许直接使用
  3. 考虑 IP 流量检测,如果同一IP 获取,会涉及大量的 IO 操作,考虑代理池
  4. 逻辑方面实际处理中,可能存在部分 广告图片,需要结合网站实际需求进行处理
  5. 如果对图片有要求,可以适当的添加一些图片大小,模糊度的的过滤条件

下面为一个简单的脚本,以百度图库为 Demo,在实际的生产项目中,可以使用 ASGI 相关支持异步的 Web 框架处理 ( 比如 tornado 等),基于事件循环,不会阻塞 网络IO,有很高的并发性。


#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File    :   dow_img_file.py
@Time    :   2023/11/15 20:53:40
@Author  :   Li Ruilong
@Version :   1.0
@Contact :   liruilonger@gmail.com
@Desc    :   批量图片采集
"""

# here put the import lib
import requests
import base64
import pandas as pd
import time
import io
import uuid
from selenium import webdriver
from selenium.webdriver.common.by import By
from PIL import Image



"""


"""


def get_img_url_base64(url):
    """
    @Time    :   2023/05/29 21:50:42
    @Author  :   liruilonger@gmail.com
    @Version :   1.0
    @Desc    :   图片 url 解析为 base64 编码
                 Args:
                   url
                 Returns:
                   base64_bytes
    """
    response = requests.get(url)
    image_bytes = response.content
    base64_bytes = base64.b64encode(image_bytes)
    return base64_bytes.decode('utf-8')


def save_base64_image(base64_data, output_file):
    """
    @Time    :   2023/11/15 22:17:15
    @Author  :   liruilonger@gmail.com
    @Version :   1.0
    @Desc    :   保存 b64 编码为 图片
    """
    
    # 解析 Base64 编码字符串
    format, data = base64_data.split(";base64,")
    image_format = format.split("/")[-1]

    # 解码 Base64 数据
    image_data = base64.b64decode(data)

    # 将字节数据读取为图像
    image = Image.open(io.BytesIO(image_data))
    image = image.convert("RGB")
    # 保存图像为文件
    image.save(output_file, image_format)


def get_img_url_byte(url):
    """
    @Time    :   2023/10/15 23:49:10
    @Author  :   liruilonger@gmail.com
    @Version :   1.0
    @Desc    :   图片 url 解析为 字节
    """
    response = requests.get(url)
    image_bytes = response.content
    return image_bytes


driver = webdriver.Chrome()

driver.get('https://image.baidu.com/')


driver.find_element(By.XPATH, "//input[@id='kw']").send_keys("K8s")
time.sleep(3)
driver.find_element(By.XPATH, "//input[@class='s_newBtn']").click()
time.sleep(5)

# 懒加载数据处理,点击 10 次加载更多
for page in range(0,2):
    # 跳转的页底部,触发懒加载
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
    time.sleep(2)
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
    time.sleep(2)
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
    time.sleep(3)

img_elements = driver.find_elements(By.TAG_NAME,'img')
time.sleep(1) 


# 对采集处理数据进行加工
imgs = []
data = {
        "URI":[],
    }
for img_element in img_elements:
    img_id = img_element.get_attribute('id')
    img_src = img_element.get_attribute('src')
    if img_src is not None and len(img_src) > 10:
        imgs.append((img_id,img_src))
        data['URI'].append(img_src)



# 这里可以根据实际清理输出表格
df = pd.DataFrame(data)
file_name = "img_url"
df.to_csv(f'{file_name}.csv', index=False) 

# 批量下载图片
for img in  imgs:
    if 'base64' in img[1]:
        save_base64_image(img[1],f"{str(uuid.uuid4()).replace('-', '')}.jpg")
    else:    
        image_bytes = get_img_url_byte(img[1])
        image = Image.open(io.BytesIO(image_bytes))
        image = image.convert("RGB")
        image.save(f"{str(uuid.uuid4()).replace('-', '')}.jpg")

测试结果

下载图片

在这里插入图片描述

保存的 图片 URI

在这里插入图片描述


© 2018-2023 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/157336.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

腾讯待办关停之后,如何提醒待办事项?

如果你之前使用腾讯待办这款小程序来记录待办事项并设置提醒,就会发现近日弹出的“业务关停通知”公告,由于业务方向调整,腾讯待办将于2023年的12月20日全面停止运营并下架,这表示以后无法继续使用了。但是腾讯待办关停之后&#…

别再吐槽大学教材了,来看看这些网友强推的数学神作!

前言 关于大学数学教材的吐槽似乎从来没停止过。有人慨叹:数学教材晦涩难懂。错!难懂,起码还可以读懂。数学教材你根本读不懂;也有人说:数学教材简直就是天书。 数学教材有好有坏,这话不假,但更…

学会使用这个平台,教你制作出色的产品画册?

产品画册是企业和用户之间的桥梁,它可以第一时间给用户传递我们企业的最新产品信息。如何制作一本精美的产品画册呢? 这个不难,给大家推荐一款免费实用的在线制作工具FLBOOK ,用这个平台可以轻松制作精美电子产品画册。 在制作产…

Python递归函数的定义和几个小例子

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 递归函数 (1)什么是递归函数? 我们都知道,一个函数可以调用其他函数。如果这个函数在内部调用它自己,那么这个…

纯前端模板文件下载如何精确控制下载的文件名字

在写项目的时候,遇到了一个需要把给定的文件放到页面中,然后用户点击下载按钮将这个文件下载下来,我将其存入了云服务之中(这个云服务是不会清空的,内存又不值几个钱),但是当我下载的时候,下载的文件名是存…

「校园 Pie」 系列活动正式启航,首站走进南方科技大学!

PieCloudDB 社区校园行系列活动「校园 Pie」已正式启动。「校园 Pie」旨在促进数据库领域的学术交流,提供一个平台让学生们了解最新的数据库发展趋势和相关技术应用。 在「校园 Pie」系列活动中,PieCloudDB 社区将携拓数派技术专家,社区大咖…

LLM建模了什么,为什么需要RAG

LLM近期研究是井喷式产出,如此多的文章该处何处下手,他们到底又在介绍些什么、解决什么问题呢?“为学日增,为道日损”,我们该如何从如此多的论文中找到可以“损之又损以至于无”的更本质道或者说是这个方向的核心模型。…

轻松玩转华为MateX5分屏功能,乐趣层出不穷!

✅小窗交互,沉浸体验不打断; ✅分区截屏,花式截图,一招搞定; ✅跨屏拖拽,随心分享易如反掌; ✅悬停视频会议,沟通效率大不同。

广州华锐互动VRAR:利用VR开展刑事案件公安取证培训,沉浸式体验提升实战能力

随着科技的飞速发展,虚拟现实(VR)技术为我们的生活和工作带来了前所未有的便利。近年来,VR技术在刑事案件公安取证培训中的应用逐渐显现出其独特优势。通过模拟真实的犯罪现场,VR技术为学员提供了沉浸式的体验,使他们在安全的环境…

LeetCode---117双周赛---容斥原理

题目列表 2928. 给小朋友们分糖果 I 2929. 给小朋友们分糖果 II 2930. 重新排列后包含指定子字符串的字符串数目 2931. 购买物品的最大开销 一、给小朋友们分糖果I 看一眼数据范围,如果没有啥其他想法思路就直接暴力,时间复杂度O(n^2) 思路&#x…

GB28181学习(十六)——基于jrtplib实现tcp被动和主动收流

前言 GB/T28181-2022实时流的传输方式介绍:https://blog.csdn.net/www_dong/article/details/134255185 tcp passive收流 流程图 注意: m字段指定传输方式为TCP/RTP/AVP;sdp信息中增加"asetup:passive";SIP服务器启…

STM32踩坑:LAN8720未接网线,上电后再接网线,网络模块无法正常使用

LAN8720未接网线,上电后再接网线,网络模块无法正常使用 一、问题描述 最近因为做的项目出了BUG,STM32 单片机在未接网线的状态下,上电一段时间后,将网线插入网口后,IP地址ping不通,网络模块无…

股票魔法师第二阶段趋势模板选股公式,寻找上涨趋势

对于股票运行的阶段,不同的股票分析方法有着不同的划分方式。从传统的主力运作分析,可以分为吸筹、洗盘、试盘、拉升、出货五个阶段。在波浪理论中,一个完整的上升或下降周期包含8浪(其中5浪是主浪、3浪是调整浪)。在缠…

Unity中Shader纹理的多级渐远Mipmap

文章目录 前言一、什么是Mipmap二、Mipmap能带来什么好处1、增加缓存命中率,减少像素抖动感2、可配合质量设置来分级加载,减少不同配置下的内存 二、我们在Shader中实现一下该效果1、我们先布置一个简单的棋盘格,用于测试纹理的多级效果2、我…

vue3 + ts项目(无vite)报错记录

记录项目创建后遇到的报错 1.类型“Window & typeof globalThis”上不存在属性“_CONFIG”。ts(2339) 问题描述: 使用全局 window 上自定义的属性,TypeScript 会报属性不存在 解决:需要将自定义变量扩展到全局 window 上&#xff0c…

MetaCyc、KEGG傻傻分不清?

今天小编从以下三点给大家唠一唠:MetaCyc数据库介绍、与KEGG比较、使用方法。 一、MetaCyc数据库介绍 MetaCyc全称Metabolic Pathways From all Domains of Life,属于BioCyc子数据库,BioCyc是一个专注于代谢通路的高质量数据库。MetaCyc是一个…

完整版指南:企业网络中的VXLAN-BGP-EVPN

随着互联网的发展,数据中心的数量和规模呈爆炸性增长趋势。数据中心业务不断增加,用户需求不断提高。随之而来的问题是数据中心的功能变得越来越复杂,运维管理变得越来越困难。VXLAN-BGP-EVPN的出现为企业网络带来了无限的可能性。 什么是VX…

跟李沐学AI-深度学习课程00-03【预告、课程安排、深度学习介绍、安装】

目录 00 预告 01 课程安排 02 深度学习介绍 03 安装 本地安装 04 数据操作数据预处理 数据操作 数据类型 创建数组 访问元素 数据操作实现 入门 运算符 广播机制 索引和切片 节省内存 转换为其他Python对象 数据预处理实现 读取数据集 处理缺失值 转换为张…

vue下载xlsx表格

vue下载xlsx表格 // 导入依赖库 import XLSX from xlsx; import FileSaver from file-saver; methods:{btn(){let date new Date()let Y date.getFullYear() -let M (date.getMonth() 1 < 10 ? 0 (date.getMonth() 1) : date.getMonth() 1) -let D (date.getDat…