基于 selenium 实现网站图片采集

news2025/1/21 1:01:33

写在前面


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

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


采集原理

一般情况下可以通过 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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库版本控制|一文带你快速入门

数据库版本控制是管理和跟踪数据库 schema 及相关数据随时间变化的实践。通常来说,我们使用版本控制系统和一些相关工具来保留对数据库所做修改的历史记录,使团队能够追踪变更、有效协作,并安全地部署更新。 一方面,使用版本控制系…

使用IDEA 将Eclipse java工程转为maven格式

使用IDEA 将Eclipse java工程转为maven格式 ①使用idea打开项目,在项目根目录下右键选择 Add Framework Support 选择 maven ,引入maven ②找到项目中的.classpath文件或者lib目录 根据.classpath文件或者lib目录中列举的jar包名,将其依次手…

阿里云服务器e实例40G ESSD Entry系统盘、2核2G3M带宽99元

阿里云99元服务器新老用户同享2核2G经济型e实例、3M固定带宽和40G ESSD Entry系统盘,老用户也可以买,续费不涨价依旧是99元一年,阿里云百科aliyunbaike.com分享阿里云3M带宽服务器40G ESSD Entry云盘性能说明: 阿里云99元服务器配…

Vatee万腾未来科技之航:Vatee创新引领的新纪元

在当今数字化时代,Vatee万腾科技正在开创一段引领未来的全新征程。以其卓越的创新能力和领导地位,Vatee万腾成为数字化领域的引领者。其未来科技之航展现了一种独特的数字化愿景,引领着科技创新进入新的纪元。 Vatee万腾在数字科技领域展现出…

微服务架构学习与思考

参考:微服务架构学习与思考(01):什么是微服务?微服务的优势和劣势 - 九卷 - 博客园 (cnblogs.com) 一、单体应用 在软件开发早期阶段,大家都在一个应用系统上开发。各个业务模块之间耦合也比较紧密。软件发布也是整体发布&#…

家得宝The Home Depot EDI案例

家得宝The Home Depot是一家总部位于美国的大型家居用品零售公司,成立于1978年,拥有超过2,200家零售店遍布美国、加拿大和墨西哥。该公司主要销售各种建筑材料、家居装饰产品、家具、电器、工具等商品,同时也提供家居装修和维修服务。 The Ho…

mybatis之主键返回

1.在mybatis的xml中加入 <insert id"insertUser" keyProperty"id" useGeneratedKeys"true" parameterType"com.UserAndOrder"> insert into Tuser(userName,passWord) values (#{userName},#{passWord} ) </insert&…

LangChain 组件

输入输出模块 该模块负责与LLM做交互&#xff0c;通过该接口向模型输入 Prompt 并提取模型输出信息。主要包括&#xff1a;提示词、语言模型&#xff0c;输出解析器。 数据连接 已训练好的大语言模型&#xff0c;在训练时使用了大量的训练数据&#xff0c;但这些训练数据中可能…

SQL编写规范【干货】

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目 2 SQL书写规范 3 SQL编写原则 获取所有软件开发资料&#xff1a;点我获取

关于git 解决分支冲突问题(具体操作,包含截图,教你一步一步解决冲突问题)

当在Git中有多个开发者在同一个分支上工作时&#xff0c;可能会发生分支冲突。分支冲突指的是多个开发者在同一时间修改相同的代码文件&#xff0c;导致Git无法自动合并这些更改。 比如说&#xff1a;我在github上进行了md文件的修改&#xff0c;我在本地仓库里面也进行md文件…

云渲染的“公”“私”技术!

当下云渲染技术主要从以下两个方面进行赋能&#xff1a; 一、云渲染公有化结构--“云计算” 云渲染公有化结构是指三维应用云渲染服务&#xff0c;以自研云流送技术为核心&#xff0c;利用云端海量 GPU 算力资源处理繁重的图像渲染计算&#xff0c;并串流同步输出到终端设备从…

Google codelab WebGPU入门教程源码<3> - 绘制网格(源码)

对应的教程文章: https://codelabs.developers.google.com/your-first-webgpu-app?hlzh-cn#4 对应的源码执行效果: 对应的教程源码: 此处源码和教程本身提供的部分代码可能存在一点差异。 class Color4 {r: number;g: number;b: number;a: number;constructor(pr 1.0, p…

时区、时间戳、时间点三者的关系

时区、时间戳、时间点这三个概念与Java的Date类和Calendar类紧密联系。分别说说区别。然后说一下Java的Date类和Calendar类 1. 时间戳 时间戳指的就是Unix时间戳(Unix timestamp)。它也被称为Unix时间(Unix time)、POSIX时间(POSIX time)&#xff0c;是一种时间表示方式&…

单词故事嵌入:通过自然语言处理解开叙事

一、介绍 在自然语言处理和文本分析领域&#xff0c;寻求理解和表示人类叙事丰富而复杂的结构是一个持续的挑战。在研究人员和数据科学家可以使用的众多工具和技术中&#xff0c;“Word Story Embeddings”作为一种创新且有前景的方法脱颖而出。这些嵌入建立在词嵌入的基础上&a…

深度学习OCR中文识别 - opencv python 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习OCR中文识别系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;…

Jmeter- Beanshell语法和常用内置对象(网络整理)

在利用jmeter进行接口测试或者性能测试的时候&#xff0c;我们需要处理一些复杂的请求&#xff0c;此时就需要利用beanshell脚本了&#xff0c;BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的。beans…

入职算法工程师后敲的非常有趣使用的小工具

NOTE&#xff1a;代码仅用来参考&#xff0c;没时间解释啦&#xff01; &#x1f349;一、自动从数据库从抽取数据。 在某台服务器中&#xff0c;从存放数据集的数据库自动抽取标注好的数据标签&#xff0c;这一步操作有什么用呢&#xff1f;当我们发现我们数据不均衡的时候&a…

OpenSign:安全可靠的电子签名解决方案 | 开源日报 No.76

microsoft/Web-Dev-For-Beginners Stars: 71.5k License: MIT 这个开源项目是一个为期 12 周的全面课程&#xff0c;由微软云倡导者团队提供。它旨在帮助初学者掌握 JavaScript、CSS 和 HTML 的基础知识。每一节都包括预习和复习测验、详细的书面指南、解决方案、作业等内容。…

中小企业如何最大程度地利用CRM系统的潜力?

在当今竞争激烈的商业世界中&#xff0c;客户关系管理&#xff08;CRM&#xff09;数字化转型已经成为大企业成功的重要秘诀。大型跨国公司如亚马逊、苹果和微软等已经在CRM数字化方面走在了前列&#xff0c;实现了高度个性化的客户体验&#xff0c;加强了客户忠诚度。 然而&a…

UI自动化测试框架的搭建(详解)

前言 今天给大家分享一个seleniumtestngmavenant的UI自动化&#xff0c;可以用于功能测试&#xff0c;也可按复杂的业务流程编写测试用例&#xff0c;今天此篇文章不过多讲解如何实现CI/CD&#xff0c;只讲解自己能独立搭建UI框架&#xff0c;需要阅读者有一定的java语言基础&…