Python爬虫——使用socket模块进行图片下载
Python爬虫——使用socket模块进行图片下载
- 什么是socket
- 爬虫的工作流程
- socket爬取图片
- 为什么能用socket能下载图片
- socket下载图片和request下载图片的区别
- 使用socket下载一张图片
- 使用socket下载多张图片
- 方法1
- 方法2
什么是socket
Socket 是一种通信机制,用于实现网络上的进程间通信。它是一种应用层协议,通常基于 TCP/IP 协议栈,可以在不同的计算机之间进行通信。Socket 本质上是一个文件描述符,它提供了一组用于网络通信的 API 接口,可以进行数据传输、建立连接、监听端口等操作。
使用 Socket 可以实现不同计算机之间的进程间通信,例如客户端和服务器之间的通信,也可以实现同一计算机内不同进程之间的通信。Socket 可以支持不同的传输协议,例如 TCP 和 UDP,可以根据需要选择不同的协议来进行通信。
在 Python 中,使用 socket 模块可以实现 Socket 编程,可以创建客户端和服务器端程序,进行网络通信。Socket 编程可以用于开发网络应用程序,例如网络爬虫、聊天室、文件传输等。
方法 | 描述 |
---|---|
connect( (host,port) ) | host代表服务器主机名或IP,port代表服务器进程所绑定的端口号。 |
send | 发送请求信息 |
recv | 接收数据 |
爬虫的工作流程
爬虫的工作流程
- 获取到资源地址:
爬虫首先要做的工作就是获取数据的资源地址,有了准确的地址之后我们才能数据去进行发送请求
- 发送请求获取数据
第二步要做的工作就是获取网页,这里就是获取网页的源代码。源代码里包含了网页的部分有用信息,所以 只要把源代码获取下来,就可以从中提取想要的信息了。
- 反爬虫处理:
有些网站会采取反爬虫措施,例如设置访问频率限制、验证码等,需要针对这些措施进行处理,以保证爬虫程序的正常运行。可以使用 Python 的验证码识别等技术来处理反爬虫措施。
- 提取信息:
获取网页源代码后,接下来就是分析网页源代码,从中提取我们想要的数据。首先,最通用的方法便是采用正则表达式提取,这是一个万能的方法,但是在构造正则表达式时比较复杂且容易出错。 另外,由于网页的结构有一定的规则,所以还有一些根据网页节点属性、CSS选择器或 XPath来提取网页信息的库,如Beautiful Soup、pyquery、lxml 等。使用这些库,我们可以高效快速地从中提取网页信 息,如节点的属性、文本值等。 提取信息是爬虫非常重要的部分,它可以使杂乱的数据变得条理清晰,以便我们后续处理和分析数据。
- 保存数据:
提取信息后,我们一般会将提取到的数据保存到某处以便后续使用。这里保存形式有多种多样,如可以简单保 存为 TXT 文本或 JSON 文本,也可以保存到数据库,如 MySQL 和 MongoDB 等,也可保存至远程服务 器,如借助 SFTP 进行操作等。
- 爬虫控制:
爬虫程序需要控制爬取的网页数量和频率,以避免对目标网站造成过大的负荷。可以使用 Python 的多线程或者多进程来实现并发爬取,也可以使用时间控制来控制爬取频率。
- 数据分析:
获取到数据后,可以进行数据分析和处理,例如数据可视化、机器学习、自然语言处理等,以得到更有价值的信息。
socket爬取图片
为什么能用socket能下载图片
使用 Socket 可以下载图片的原因是因为 HTTP 协议是基于 Socket 的应用层协议,它使用 TCP/IP 协议族来传输数据。在 HTTP 协议中,客户端通过 Socket 建立连接到服务器,发送请求,服务器接收请求并返回响应,客户端接收响应并处理响应数据。
由于 HTTP 协议是基于 Socket 的,所以使用 Socket 可以直接发送 HTTP 请求和接收 HTTP 响应,实现数据的传输和下载。使用 Socket 下载图片需要手动构造 HTTP 请求和解析 HTTP 响应,需要编写更多的代码来处理数据传输和错误处理,但是相对于其他下载方式,使用 Socket 可以更加灵活和自定义,可以实现更多的功能和应用场景。
socket下载图片和request下载图片的区别
Socket 和 Request 都可以用于下载图片,但是它们的实现方式和用途略有不同。
Socket 是一种底层的网络通信协议,它可以在应用层和传输层之间建立连接,进行数据传输。使用 Socket 下载图片需要手动构建 HTTP 请求和解析 HTTP 响应,需要编写更多的代码来处理数据传输和错误处理。Socket 更适合于底层网络通信的应用,如实现自定义协议、网络游戏等。
Request 是一个 Python 库,它封装了 HTTP 请求和响应的处理,可以方便地进行网络请求。使用 Request 下载图片只需要简单的代码就可以完成,而且可以方便地设置请求头、请求参数等信息。Request 更适合于开发网络爬虫、数据采集等应用。
总的来说,使用 Socket 下载图片更加底层、灵活,但需要编写更多的代码;使用 Request 下载图片更加高层、方便,但可能会有一些限制。选择使用哪种方式,取决于具体的需求和应用场景。
用代码举例说明:
使用 Socket下载图片:
import socket# 构造 HTTP 请求
request = b"GET /images/test.jpg HTTP/1.1\r\nHost: example.com\r\n\r\n"# 建立连接并发送请求
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("example.com", 80))
s.send(request)# 接收响应并保存图片
response = s.recv(4096)
while response:if b"Content-Type: image/jpeg" in response:with open("test.jpg", "wb") as f:f.write(response)breakresponse = s.recv(4096)# 关闭连接
s.close()
使用 Request 下载图片:
import requests# 发送请求并保存图片
response = requests.get("http://example.com/images/test.jpg")
with open("test.jpg", "wb") as f:f.write(response.content)
可以看到,使用 Request 下载图片更加简单和方便,而使用 Socket 则需要手动构建 HTTP 请求和解析 HTTP 响应,需要更多的代码和处理过程。
使用socket下载一张图片
以图片http://image11.m1905.cn/uploadfile/2021/0922/thumb_0_647_500_20210922030733993182.jpg
为例。
想要使用socket下载这张图片,具体步骤如下:
-
获取到资源地址 url。
-
创建 Socket 客户端对象 client,并连接到服务器 image11.m1905.cn 的端口 80。
-
构造 HTTP 请求,包括请求方法、请求地址、请求协议版本、请求头等信息,并发送请求。
-
循环接收服务器响应,并将响应数据添加到二进制对象 result 中。
-
使用正则表达式提取响应数据中的图片数据,即去掉响应头部分。
-
将图片数据存储到本地文件中,即下载图片到本地。
代码如下:
import socket
import re
import time# 获取到资源地址
url = 'http://image11.m1905.cn/uploadfile/2021/0922/thumb_0_647_500_20210922030733993182.jpg'start = time.time()# 创建套接字对象
client = socket.socket()# 创建连接
client.connect(('image11.m1905.cn', 80))# 构造http请求
http_res = 'GET ' + url + ' HTTP/1.0\r\nHost: image11.m1905.cn\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36\r\n\r\n'
# print(http_res)# 发送请求
client.send(http_res.encode())
# 建立一个二进制对象用来存储我们得到的数据result = b''
data = client.recv(1024)# 循环接收响应数据 添加到bytes类型
while data:result += datadata = client.recv(1024)
# print(result)# 提取数据
# re.S使 . 匹配包括换行在内的所有字符去掉响应头
images = re.findall(b'\r\n\r\n(.*)', result, re.S)
# print(images[0])# 打开一个文件,将我们读取到的数据存入进去,即下载到本地我们获取到的图片
with open('小姐姐.png', 'wb')as f:f.write(images[0])end_time = time.time() # 记录结束时间
elapsed_time = end_time - start # 计算代码执行时间
print(f'All images downloaded successfully in {elapsed_time:.2f} seconds')
使用socket下载多张图片
假设我们想使用socket下载多张图片,我这里给出两种实现方法。
方法1
将需要下载的url做成一个列表,再使用split函数将url中的/
进行分割,然后通过切片方法得到url中的相对路径和host值,最后通过循环遍历url列表,达到下载多张图片的效果。代码如下
import socket
import re
import time
start = time.time()
# 获取到的资源地址
urls = ['https://pic.netbian.com/uploads/allimg/220211/004115-1644511275bc26.jpg','https://pic.netbian.com/uploads/allimg/220215/233510-16449393101c46.jpg','https://pic.netbian.com/uploads/allimg/211120/005250-1637340770807b.jpg'
]# 创建连接
for url in urls:# 解析URLparts = url.split('/') # ['https:', '', 'pic.netbian.com', 'uploads', 'allimg', '220211', '004115-1644511275bc26.jpg']host = parts[2] # pic.netbian.compath = '/' + '/'.join(parts[3:]) # /uploads/allimg/220211/004115-1644511275bc26.jpg# print(parts)# print(host)# print(path)# 创建套接字对象连接到主机client = socket.socket()client.connect((host, 80))# 构造HTTP请求http_req = f'GET {path} HTTP/1.1\r\nHost: {host}\r\nuser-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' \f'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36\r\nConnection: close\r\n\r\n '# print(http_req)# 发送请求client.sendall(http_req.encode())# 接受响应数据result = b''data = client.recv(1024)while data:result += datadata = client.recv(1024)# 提取图像数据images = re.findall(b'\r\n\r\n(.*)', result, re.S)# print(images[0])# 写入文件if images:with open(f'{parts[-1]}', 'wb') as f:f.write(images[0])else:print(f'No image data received for {url}')# 关闭连接client.close()end_time = time.time() # 记录结束时间
elapsed_time = end_time - start # 计算代码执行时间
print(f'All images downloaded successfully in {elapsed_time:.2f} seconds')
方法2
通过创建线程池,使用多线程的方式同时下载所有图片。
代码如下:
import socket
import re
import multiprocessing
import timedef download_image(url):# 解析URLparts = url.split('/')host = parts[2]path = '/' + '/'.join(parts[3:])# 创建套接字对象连接到主机client = socket.socket()client.connect((host, 80))# 构造HTTP请求http_req = f'GET {path} HTTP/1.1\r\nHost: {host}\r\nuser-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' \f'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36\r\nConnection: close\r\n\r\n '# 发送请求client.sendall(http_req.encode())# 接受响应数据result = b''data = client.recv(1024)while data:result += datadata = client.recv(1024)# 提取图像数据images = re.findall(b'\r\n\r\n(.*)', result, re.S)# 写入文件if images:with open(f'{parts[-1]}', 'wb') as f:f.write(images[0])else:print(f'No image data received for {url}')# 关闭连接client.close()if __name__ == '__main__':start = time.time()urls = ['https://pic.netbian.com/uploads/allimg/220211/004115-1644511275bc26.jpg','https://pic.netbian.com/uploads/allimg/220215/233510-16449393101c46.jpg','https://pic.netbian.com/uploads/allimg/211120/005250-1637340770807b.jpg']# 创建进程池pool = multiprocessing.Pool(processes=3)# 同时下载所有图片pool.map(download_image, urls)# 关闭进程池pool.close()pool.join()end = time.time()elapsed_time = end - start # 计算代码执行时间print(f'All images downloaded successfully in {elapsed_time:.2f} seconds')
相关文章:

Python爬虫——使用socket模块进行图片下载
Python爬虫——使用socket模块进行图片下载什么是socket爬虫的工作流程socket爬取图片为什么能用socket能下载图片socket下载图片和request下载图片的区别使用socket下载一张图片使用socket下载多张图片方法1方法2什么是socket Socket 是一种通信机制,用于实现网络…...

通用游戏地图解决方案设计解析
前言: 在软件开发过程中,我们都希望能设计出一个稳健的,可维护的系统,为了实现这个目的,人们总结出了很多相关的设计原则,比如SOLID原则, KISS原则等等。SOLID每个字母代表了一种设计原则&…...

java @Autowired @Resource @Inject 三个注解的区别
javax.annotation.Resourcejdk 内置的,JSR-250 中的注解。依赖注入通过 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 来处理。org.springframework.beans.factory.annotation.Autowired org.springframework.beans.factory.annotati…...

「媒体分流直播」媒体直播和传统直播的区别,以及媒体直播的特点
传媒如春雨,润物细无声,大家好直播毋庸置疑已经融入到了我们生活的方方面面,小到才艺,游戏,大到政策的发布,许多企业和机构也越来越重视直播,那么一场活动怎么最大化的进行传播,一是…...

数据是如何在计算机中存储的
我们普通人对于数据存储的认识恐怕大多数都是从自己使用的电脑来的。现在几乎人手一台电脑,而我们的电脑存储着各种各样的文件,比如视频文件、音频文件和Word文档等。这些文件从计算机术语的角度都可以称为数据。 如图1-1所示是Windows 10 “我的电脑”的截图。通过该截图我…...

Day907.分区表 -MySQL实战
分区表 Hi,我是阿昌,今天学习记录的是关于分区表的内容。 经常被问到这样一个问题: 分区表有什么问题,为什么公司规范不让使用分区表呢? 一、分区表是什么? 为了说明分区表的组织形式,先创建…...

C++概览:工具链、基础知识、进阶及总结
本篇写给C初学者,作为概览,文中仅包含各方面基础知识,无深入分析。 C基础概念简介 C编译过程示意图 关键词:源文件、预编译、编译、汇编、链接 C工具链总结 cmake项目工程文件是一种中介工程文件,可以转化成其他…...

目标检测中回归损失函数(L1Loss,L2Loss,Smooth L1Loss,IOU,GIOU,DIOU,CIOU,EIOU,αIOU ,SIOU)
文章目录L-norm Loss 系列L1 LossL2 LossSmooth L1 LossIOU系列IOU (2016)GIOU (2019)DIOU (2020)CIOU (2020)EIOU (2022)αIOU (2021)SIOU (2022…...

JOSN数据转换和解析
文章目录JOSN数据转换和解析内容回顾Map 集合转成 JSON 字符串List 集合转换成 JSON 字符串Ajax 异步和同步异步概念同步概念异步和同步区别异步请求案例同步请求时间格式化旧时间 api 格式化格式化和解析的工具类JSTL 时间格式化JSTL 使用JOSN数据转换和解析 内容回顾 ajax …...

浅析Linux内核中进程完全公平CFS调度
一、前序 目前Linux支持三种进程调度策略,分别是SCHED_FIFO 、 SCHED_RR和SCHED_NORMAL;而Linux支持两种类型的进程,实时进程和普通进程。实时进程可以采用SCHED_FIFO 和SCHED_RR调度策略;普通进程则采用SCHED_NORMAL调度策略。从…...

安装 RustDesk 服务器 (适用 Rocky Linux, CentOS, RHEL 系列发行版)
环境:Rocky Linux 9.1 1. 安装 Docker Engine 可以参考 [[linux-docker-rocky-install]] https://cc01cc.com/2023/03/02/linux-docker-rocky-install/英文可以参考官方文档 Install Docker Engine on RHEL https://docs.docker.com/engine/install/rhel/ 2. 安装…...

23种设计模式-策略模式
策略模式是一种设计模式,它允许在运行时选择算法的行为。它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户端。在本文中,我们将深入探讨策略模式的概念和实际应用&#…...

C#开发的OpenRA的游戏主界面怎么样创建
通过前面加载界面布局数据,可以把整个界面逻辑的数据加载到内存, 但是这些数据怎么显示出来,又是没有定义的。比如前面定义了多个界面的布局, 又是怎么样知道需要显示哪一个界面? 现在就来解决这个问题,其实整个游戏都是可以通过yaml文件进行配置的, 所以我们需要从yaml…...

考研还是工作?两战失败老道有话说
老道入职第一周自我介绍谈谈考研谈谈工作新的启程自我介绍 大家好!在下是一枚考研失败两次的自认为聪明能干的有点小帅的实则超级垃圾的三非名校毕业的自动化渣男。大一下就加入实验室,在实验室焊板子、画板子、培训、打比赛外加摸鱼;参加过…...

引用是否有地址的讨论的
说在前头,纯属个人理解,关于引用是否有地址,实际上并没有一个很统一的说法, C标准没有规定一个引用是否需要占用一块内存。 这里引用知乎“C 中引用是一块内存的标记,那引用本身有地址吗_百度知道 (baidu.com)”里面的…...

1、JAVA 开发环境搭建 - JDK 的安装配置
文章目录一、下载 JDK81、官网地址:[**https://www.oracle.com**](https://www.oracle.com)二、安装 JDK1、鼠标右键安装包,以管理员身份运行(无脑下一步即可)2、细节说明三、配置环境变量1、为啥要配置环境变量呢?2、原因分析3、配置环境变量…...

【Storm】【六】Storm 集成 Redis 详解
Storm 集成 Redis 详解 一、简介二、集成案例三、storm-redis 实现原理四、自定义RedisBolt实现词频统计一、简介 Storm-Redis 提供了 Storm 与 Redis 的集成支持,你只需要引入对应的依赖即可使用: <dependency><groupId>org.apache.storm…...

算法代码题——模板
文章目录1. 双指针: 只有一个输入, 从两端开始遍历2. 双指针: 有两个输入, 两个都需要遍历完3. 滑动窗口4. 构建前缀和5. 高效的字符串构建6. 链表: 快慢指针7. 反转链表8. 找到符合确切条件的子数组数9. 单调递增栈10. 二叉树: DFS (递归)]11. 二叉树: DFS (迭代)12. 二叉树: …...

CentOS 7.9汇编语言版Hello World
先下载、编译nasm汇编器。NASM汇编器官网如下图所示: 可以点图中的List进入历史版本下载网址: 我这里下载的是nasm-2.15.05.tar.bz2 在CentOS 7中,使用 wget http://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2下载…...

CoreData数据库探索
CoreData是什么 Core Data 是苹果公司提供的一个对象-关系映射框架(Object-Relational Mapping,ORM),用于管理应用程序的数据模型。Core Data 提供了一个抽象层,使开发人员能够使用面向对象的方式访问和操作数据&…...

FreeRTOS入门
目录 一、简介 二、堆的概念 三、栈的概念 四、从官方源码中精简出第一个FreeRTOS程序 五、修改官方源码增加串口打印 一、简介 FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、…...

JVM运行时数据区划分
Java内存空间 内存是非常重要的系统资源,是硬盘和cpu的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM内存布局规定了JAVA在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。不同的jvm对于内存的划分方式和管理机…...

重装系统一半电脑蓝屏如何解决
小编相信大家在使用电脑或者给电脑重装系统的时候都遇到过电脑蓝屏等等故障问题。最近有用户就遇到了这样一个问题,问小编重装系统一半电脑蓝屏怎么办,那么今天小编就告诉大家重装系统一半电脑蓝屏的解决方法。 工具/原料: 系统版本&#x…...

SpringBoot(tedu)——day01——环境搭建
SpringBoot(tedu)——day01——环境搭建 目录SpringBoot(tedu)——day01——环境搭建零、今日目标一、IDEA2021项目环境搭建1.1 通过 ctrl鼠标滚轮 实现字体大小缩放1.2 自动提示设置 去除大小写匹配1.3 设置参数方法自动提示1.4 设定字符集 要求都使用UTF-8编码1.5 设置自动编…...

springboot整合redis
1.redis的数据类型,一共有5种.后面结合Jedis和redistemplate,以及单元测试junit一起验证 1)字符串 2)hash 3)列表 4)set(无序集合) 5)zset(有序集合) 2.Jedis的使用 a)引入依赖 <!--加入springboot的starter的起步依赖--><dependency><groupId>…...

【Java】Spring Boot下的MVC
文章目录Spring MVC程序开发1. 什么是Spring MVC?1.1 MVC定义1.2 MVC 和 Spring MVC 的关系2. 为什么学习Spring MVC?3. 怎么学习Spring MVC?3.1 Spring MVC的创建和连接3.1.1 创建Spring MVC项目3.1.2 RequestMapping 注解介绍3.1.3 Request…...

【项目精选】 塞北村镇旅游网站设计(视频+论文+源码)
点击下载源码 摘要 城市旅游产业的日新月异影响着村镇旅游产业的发展变化。网络、电子科技的迅猛前进同样牵动着旅游产业的快速成长。随着人们消费理念的不断发展变化,越来越多的人开始注意精神文明的追求,而不仅仅只是在意物质消费的提高。塞北村镇旅游…...

十、Spring IoC注解式开发
1 声明Bean的注解 负责声明Bean的注解,常见的包括四个: ComponentControllerServiceRepository Controller、Service、Repository这三个注解都是Component注解的别名。 也就是说:这四个注解的功能都一样。用哪个都可以。 只是为了增强程序…...

Linux系统GPIO应用编程
目录应用层如何操控GPIOGPIO 应用编程之输出GPIO 应用编程之输入GPIO 应用编程之中断在开发板上测试GPIO 输出测试GPIO 输入测试GPIO 中断测试本章介绍应用层如何控制GPIO,譬如控制GPIO 输出高电平、或输出低电平。应用层如何操控GPIO 与LED 设备一样,G…...

手敲Mybatis-反射工具天花板
历时漫长的岁月,终于鼓起勇气继续研究Mybatis的反射工具类们,简直就是把反射玩出花,但是理解起来还是很有难度的,涉及的内容代码也颇多,所以花费时间也比较浩大,不过当了解套路每个类的功能也好,…...