Python Socket请求网站获取数据

---阻塞 I/O           ->收快递,快递如果不到,就干不了其他的活

---非阻塞I/0       ->收快递,不断的去问,有没有送到,有没有送到,...如果送到了就接收

---I/O多路复用      ->找个代理人(select), 去收快递。快递到了,就通知用户.  

一 . 阻塞方式

blocking IO 会一直block 对应的进程,直到操作完成

# 客户端请求网站-阻塞实现(一次一次的请求)
import socket
import time# 访问网站
ACCESS_URL = 'www.baidu.com'
# 端口
ACCESS_PORT = 80
# socket阻塞请求网站
def blocking(pn):sock = socket.socket()sock.connect((ACCESS_URL, ACCESS_PORT))  # 连接网站 ,发出一个HTTP请求request_url = 'GET {} HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(pn))sock.send(request_url.encode())response = b''chunk = sock.recv(1024)while chunk:  # 循环接收数据,因为一次接收不完整response += chunkchunk = sock.recv(1024)# print(response.decode())return responsedef block_way():for i in range(5):blocking(i)if __name__ == '__main__':start = time.time()block_way()print('请求5次页面耗时{}'.format(time.time() - start))"""请求5次页面耗时2.4048924446105957"""

二. 非阻塞方式

non-blcoking在kernel还没准备好数据的情况下,会立即返回(会抛出异常)

# 客户端请求网站-非阻塞实现
import socket
import time# 访问网站
ACCESS_URL = 'www.baidu.com'
# 端口
ACCESS_PORT = 80
# socket非阻塞请求网站(时间消耗在不断的while循环中,和阻塞的时间差不多)
def blocking(pn):sock = socket.socket()sock.setblocking(False)  # 设置为非阻塞try:# connect连接需要一定时间,非阻塞发送完请求,立即返回,如果没有数据会报异常sock.connect((ACCESS_URL, ACCESS_PORT))  # 连接网站 ,发出一个HTTP请求except BlockingIOError:  # 非阻塞套接字捕获异常passrequest_url = 'GET {} HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(pn))while True:  # 不断发送http请求try:sock.send(request_url.encode())breakexcept OSError:passresponse = b''while True:  # 不断地接收数据try:chunk = sock.recv(1024)  # 没有数据返回时会收到异常while chunk:  # 循环接收数据,因为一次接收不完整response += chunkchunk = sock.recv(1024)breakexcept BlockingIOError:  # 处理非阻塞异常pass# print(response.decode())return responsedef block_way():for i in range(5):blocking(i)if __name__ == '__main__':start = time.time()block_way()print('请求5次页面耗时{}'.format(time.time() - start))"""请求5次页面耗时2.681565046310425时间消耗在不断的while循环中,和阻塞的时间差不多"""

三. 多线程方式

# 客户端请求网站-线程池实现
import socket
from multiprocessing.pool import ThreadPool
import time# 访问网站
ACCESS_URL = 'www.baidu.com'
# 端口
ACCESS_PORT = 80def blocking(pn):sock = socket.socket()sock.connect((ACCESS_URL, ACCESS_PORT))  # 连接网站 ,发出一个HTTP请求request_url = 'GET {} HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(pn))sock.send(request_url.encode())response = b''chunk = sock.recv(1024)while chunk:  # 循环接收数据,因为一次接收不完整response += chunkchunk = sock.recv(1024)# print(response.decode())return responsedef block_way():pool = ThreadPool(5)for i in range(10):pool.apply_async(blocking, args=(i,))pool.close()  # close()执行后不会有新的进程加入到poolpool.join()  # join函数等待子进程结束if __name__ == '__main__':start = time.time()block_way()print('请求10次页面耗时{}'.format(time.time() - start))"""请求10次页面耗时1.1231656074523926 """

四. 多进程方式

# 客户端请求网站-进程池实现
import socket
from multiprocessing import Pool
import time# 访问网站
ACCESS_URL = 'www.baidu.com'
# 端口
ACCESS_PORT = 80def blocking(pn):"""发送请求,接收数据:param pn: :return: """sock = socket.socket()sock.connect((ACCESS_URL, ACCESS_PORT))  # 连接网站 ,发出一个HTTP请求request_url = 'GET {} HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(pn))sock.send(request_url.encode())response = b''chunk = sock.recv(1024)while chunk:  # 循环接收数据,因为一次接收不完整response += chunkchunk = sock.recv(1024)# print(response.decode())return responsedef block_way():pool = Pool(5)for i in range(10):pool.apply_async(blocking, args=(i,))pool.close()  # close()执行后不会有新的进程加入到poolpool.join()  # join函数等待子进程结束if __name__ == '__main__':start = time.time()block_way()print('请求10次页面耗时{}'.format(time.time() - start))"""请求10次页面耗时1.1685676574707031 略慢于线程池实现方式,因为进程相对于线程开销比较大"""

五. 协程方式

# 客户端请求网站-协程实现
from gevent import monkey;monkey.patch_all()  # 加补丁,实现非阻塞
import socket
import gevent
import time# 访问网站
ACCESS_URL = 'www.baidu.com'
# 端口
ACCESS_PORT = 80def blocking(pn):"""发送请求,接收数据:param pn: :return: """sock = socket.socket()sock.connect((ACCESS_URL, ACCESS_PORT))  # 连接网站 ,发出一个HTTP请求request_url = 'GET {} HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(pn))sock.send(request_url.encode())response = b''chunk = sock.recv(1024)while chunk:  # 循环接收数据,因为一次接收不完整response += chunkchunk = sock.recv(1024)# print(response.decode())return responsedef block_way():tasks = [gevent.spawn(blocking,i) for i in range (10)] #启动协程gevent.joinall(tasks)  # 阻塞等待所有操作都执行完毕if __name__ == '__main__':start = time.time()block_way()print('请求10次页面耗时{}'.format(time.time() - start))"""请求10次页面耗时0.6231002807617188 效率高于线程方式,协程相当于单线程并发(微线程),开销小于线程"""

六. IO多路复用

I/O多路复用就是通过一种机制,操作系统通过一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

# 客户端请求网站-I/O多路复用
import socket
import selectors
import time# 访问网站
ACCESS_URL = 'www.baidu.com'
# 端口
ACCESS_PORT = 80sel = selectors.DefaultSelector()
flag = False  # 结束标志
num_list = [0] * 5class Crawler(object):def __init__(self,pn):self.pn = pnself.response = b''def req_connect(self):"""请求建立连接:return:"""sock = socket.socket()sock.setblocking(False)try:sock.connect((ACCESS_URL, ACCESS_PORT))  # 连接网站 ,发出一个HTTP请求except BlockingIOError:  # 非阻塞套接字捕获异常passsel.register(sock,selectors.EVENT_WRITE, self.conn_send)  # 监听socket,向服务端发送数据WRITEdef conn_send(self,sock):"""发送请求数据:param sock::return:"""# 取消上面注册监听的套接字
        sel.unregister(sock)request_url = 'GET {} HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(self.pn))sock.send(request_url.encode())  # 当我们发送数据之后,就等接收数据
        sel.register(sock,selectors.EVENT_READ, self.read)def read(self, sock):global flagchunk = sock.recv(1024)if chunk:self.response += chunkelse:# 没有数据可读print(self.response)sel.unregister(sock)num_list.pop()if not num_list:flag = True# 事件循环
def loop():while not flag:events = sel.select() # 监听发生了变化的套接字for key, mask in events:callback = key.datacallback(key.fileobj)if __name__ == '__main__':start = time.time()# print(num_list)for i in range(5):crawler = Crawler(i)  # 实例
        crawler.req_connect()loop()print('请求5次页面耗时{}'.format(time.time() - start))"""请求5次页面耗时0.5865745544433594 多路复用非阻塞效率要高于非阻塞方式"""

转载于:https://www.cnblogs.com/xiao-apple36/p/8673356.html

Python Socket请求网站获取数据相关推荐

  1. Python爬取网站图片数据

    Python爬取网站图片数据 找到需要爬取的网站地址 模拟网站http请求 根据调试模式获取的了解读取到真实的地址url,读取请求头数据和参数信息,模拟http请求调用 import requests ...

  2. 08-Flutter移动电商实战-dio基础_伪造请求头获取数据

    08-Flutter移动电商实战-dio基础_伪造请求头获取数据 在很多时候,后端为了安全都会有一些请求头的限制,只有请求头对了,才能正确返回数据.这虽然限制了一些人恶意请求数据,但是对于我们聪明的程 ...

  3. python 东方财富接口_Python从东方财富网站获取数据,python,的

    python 获取东方财富网站的数据 #!/usr/bin/env python # -*- coding: utf-8 -*- import pandas as pd from selenium i ...

  4. python调用第三方接口获取数据_python调用接口,python接收post请求接口(附完整代码)...

    与Scala语言相比,Python有其独特的优势和广泛的应用,python调用接口,因此Spark也推出了PySpark,它在框架上提供了一个使用Python语言的接口,python接收post请求接 ...

  5. 这福利给你要不要 — 用Python采集相亲网站女生数据

    前言 俗话说学咱这行的男同志 找对象容易吗 这马上就要过完年了 是时候找找女朋友了 我在这里摸索到了个网站 或许你们可以来看看 送一波单身福利 不需要的也可以学学怎么采集这些数据呗 环境与模块 环境开 ...

  6. 练习使用Python post请求爬取数据,并用mySQL数据库进行存储

    2019独角兽企业重金招聘Python工程师标准>>> 我看了许多教程,之前练习过爬取百度百科和汽车之家,都没有成功,可能功力不到,有些问题总看不出到底是哪里出了毛病. 我看得其中有 ...

  7. python socket发送组播数据_python3通过udp实现组播数据的发送和接收操作

    本文主要通过对海康摄像头进行抓包,模拟发送了udp包,并抓取摄像头返回的数据包,解析并提取相关信息. 通过抓包发现,海康摄像头发送.接收数据使用udp协议,后来比较发现,使用python模拟起来比较简 ...

  8. python从ip端口 获取数据_python 如何获得Ip地址和端口啊?

    1.什么是爬虫 爬虫,即网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来.想抓取什么?这个由你来控制它咯. ...

  9. 如何利用python调用API接口获取数据进行测试

    一.Python 可以使用 requests 库来调用 API 接口获取数据.以下是基本的步骤: 1.安装 requests 库 pip install requests 2.导入 requests ...

最新文章

  1. swift学习之set和get方法
  2. 成功解决⑧NVIDIA安装程序无法继续 此NVIDL驱动程序与此Windows版本不兼容。 此图形驱动程序无法找到兼吝的图形硬件。
  3. Python中文分词 jieba 十五分钟入门与进阶
  4. 手把手教你怎么用动软.net代码生成器 搭建三层架构
  5. 在vSphere Client中启动虚拟机创建进程以及VMwareTools安装
  6. Python3实现简单可学习的手写体识别
  7. 网页版消消乐快速实现,无代码吗iVX 真那么简单?
  8. html+css个人博客_如何在互联网放置 HTML 页面
  9. PHP Everywhere 插件中存在严重RCE,影响数千个 WordPress 站点
  10. jsp文字上下居中显示_如何让任务栏完全透明,图标居中
  11. Spring生态系统(Spring可能大家都在用,很少去关注整体架构)
  12. Linux的顶级十六进制编辑器
  13. kasp技术优点_【华智技术贴】分子标记技术及育种应用(下):基于测序技术的第三代分子标记...
  14. 伴随方法:线性方程的伴随方程(Adjoint Equation)
  15. Matlab自动保存图像时使用saveas函数运行出错
  16. 高效工作-使用石墨文档进行信息收集
  17. Python动态网页爬取
  18. 大数据分析的好帮手 Excel函数应用的顶级实战 Excel数据分析应用+VBA实战 24G课程
  19. 如何在家利用网络副业赚钱,这三个网上副业,做好比主业更好
  20. C.Defuse the Bombs(简单二分)

热门文章

  1. Android 获取标题栏的高度
  2. 《网页设计创意书》读后感
  3. Web架构师必备能力
  4. 代码 设计 生活 (2)--- 菜鸟
  5. EOS能不能囤?一篇文章搞懂EOS优缺点
  6. 智能合约和区块链技术:入门指南
  7. Git Fetch vs Pull:Git Fetch和Git Pull命令之间有什么区别?
  8. 可视化编码_Modulz简介:可视编码的下一步
  9. 悉尼大学计算机研究生学制,悉尼大学研究生学制
  10. 1130 Infix Expression