代理服务器的定义和作用请走百度百科~

1. Web Proxy的实现思路

这是基于上一篇“编写Web Server”写的,主要逻辑见下图:

我们要写的就是中间的Web Proxy部分,当客户端向Web Proxy发送对某一个网址的访问请求(Request)时,Web Proxy会首先查看自己是否有该请求文件,如果有则直接返回(Response),如果没有,Web Proxy就要像Web Server(该访问网址的服务器)发送请求来获取目标文件,然后再向Client返回。

2. Web Proxy的使用

首先,我们在访问一个网址时为了通过代理访问就不能简单地打开浏览器输入网址进行访问(那样就变成Client直接向Web Server发送Reuest了),在这里可以下载一个名为Wget的工具,这个东西对于Web Proxy就好像是jdk对于Java一样(当然也许有其他的工具可以先访问代理服务器,这里不讨论),下载完成后可以解压就可以使用了,就像使用jdk一样首先在命令行窗口中找到该文件所在文件夹,如果不想每次都输入一串目录来查找的话也可以将这个文件的路径添加至环境变量(至于如何配置自行搜索)。

当Web Proxy和Wget都准备好之后就可以开始运行了:

首先运行Web Proxy程序,然后通过Wget请求使用代理并且发送Request

(Wget命令:wget xxx.xxx.xx -e use_proxy=on -e http_proxy=127.0.0.1:8000),其中“xxx.xxx.xx”就是你要请求的网址

3. Web Proxy源码

import socket

def handleReq(clientSocket):
# recv data
# find the fileName
# judge if the file named "fileName" if existed
# if not exists, send req to get it recvData = clientSocket.recv(1024).decode()
fileName = recvData.split()[1].split("//")[1].replace('/', '')
print("fileName: " + fileName)
try:
file = open(fileName, 'rb')
print("File is found in proxy server.")
responseMsg = file.readlines()
for i in range(0, len(responseMsg)):
clientSocket.sendall(responseMsg[i])
print("Send, done.")
except Exception:
try:
print("File is not exist.\nSend request to server...")
proxyClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverName = fileName.split(":")[0]
proxyClientSocket.connect((serverName, 80))
proxyClientSocket.sendall(recvData.encode())
responseMsg = proxyClientSocket.recv(4069)
print("File is found in server.")
proxyClientSocket.sendall(responseMsg)
print("Send, done.")
# cache
cache = open("./" + fileName, 'w')
cache.writelines(responseMsg.decode().replace('\r\n', '\n'))
cache.close()
print("Cache, done.")
except:
print("Connect timeout.") def startProxy(port):
proxyServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
proxyServerSocket.bind(("", port))
proxyServerSocket.listen(0)
while True:
try:
print("Proxy is waiting for connecting...")
clientSocket, addr = proxyServerSocket.accept()
print("Connect established")
handleReq(clientSocket)
clientSocket.close()
except Exception as e:
print("error: {0}".format(e))
break
proxyServerSocket.close() if __name__ == '__main__':
while True:
try:
port = int(input("choose a port number over 1024:"))
except ValueError:
print("Please input an integer rather than {0}".format(type(port)))
continue
else:
if port <= 1024:
print("Please input an integer greater than 1024")
continue
else:
break
startProxy(port)

4. Wget工具包

链接:https://pan.baidu.com/s/1Ae2_Cq9SYbKnfhhyJ1VhpQ
提取码:awsl

Python3网络学习案例四:编写Web Proxy的更多相关文章

  1. Python3网络学习案例三:编写web server

    1. 写在前面 这里总结的并不够详细,有时间了再进行补充. 2. 设计思路 HTTP协议是建立在TCP上的1. 建立服务器端TCP套接字(绑定ip,port),等待监听连接:listen(2. 打开浏 ...

  2. Python3网络学习案例一:Ping详解

    1. 使用Ping做什么 ping用于确定本地主机是否能与另一台主机成功交换(发送与接收)数据包,再根据返回的信息,就可以推断TCP/IP参数是否设置正确,以及运行是否正常.网络是否通畅等. 2. 效 ...

  3. Python3网络学习案例二:traceroute详解

    1. 写在前面 本文是基于上一篇"ping详解"写的: 不同操作系统下的命令也不同,本文仅针对windows系统,命令为"tracert xxx",效果如下 2 ...

  4. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

  5. Beego学习笔记四:编写Model

    MVC实践一:编写模型 1>     打开mysql数据库,设计表的结构 <1>登录mysql数据库,如下 <2>这三个标注的参数皆有用,需要谨记. <3>创 ...

  6. python3语法学习第四天--字符串

    字符串:是python中的常用数据类型 Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用 访问字符串的值: 下标和分片截取 字符串的连接:‘+’ 字符串内置函数挺多,选 ...

  7. python3语法学习第四天--序列

    序列是Python中最基本的数据结构. 序列中的每个元素都分配一个索引从0开始依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列可以的操作:索引,切片,加,乘,检查成员. 此 ...

  8. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

  9. 从零开始学习PYTHON3讲义(十四)写一个mp3播放器

    <从零开始PYTHON3>第十四讲 通常来说,Python解释执行,运行速度慢,并不适合完整的开发游戏.随着电脑速度的快速提高,这种情况有所好转,但开发游戏仍然不是Python的重点工作. ...

随机推荐

  1. Python-迭代协议-__iter__ __next__ iter next yield

    iter 本质是for循环调用的实质,for循环通过调用这个函数返回可迭代对象生成器形式,开始迭代取值捕获StopIteration错误退出循环 for循环首先找__iter__方法,然后再找 __g ...

  2. Python-类属性查询协议-__getattr__ __getattribute__

    __getattr__ 查找不到类属性的时候调用 class BeiMenChuiXue: def __init__(self, name): self.name = name def __getat ...

  3. 029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑“非”运算符

    029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑"非"运算符 本文知识点:Java中的逻辑"非"运算符 逻辑& ...

  4. 03 sublime text3下配置Java的编译运行环境

    参考如下文章,加入了自己的干货: https://blog.csdn.net/qq_38295511/article/details/81140069 https://blog.csdn.net/qq ...

  5. 《穷查理年鉴》习惯 & 工作 & 自省 & 自律 (关于自己)

    习惯 001.在那充满古老年鉴的年代里,扔掉你的恶行,不管它们曾经给你带来多大的好处. 002.许多关于预言的争论都可以简化为:当你说是时,就有人说浊;当你认为不是时,一定有人说是. 003.坏习惯和 ...

  6. devops-jenkins基于角色的权限管理RBAC

    一. devops-jenkins基于角色的权限管理RBAC 1 安装角色的rbac角色管理  1.1) 点击系统管理 1.2) 选择插件管理 1.3) 选择可选插件,输入role搜索 1.4) 选择 ...

  7. client: c#+protobuf, server: golang+protobuf

    前段时间看到一篇博文<可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)>,他是用C#实现的即时通讯系统,功能强大,界面漂亮. 就想用golang重写服务端,把代码下载 ...

  8. C# 范型约束 new() 你必须要知道的事

    C# 范型约束 new() 你必须要知道的事 注意:本文不会讲范型如何使用,关于范型的概念和范型约束的使用请移步谷歌. 本文要讲的是关于范型约束无参构造函数 new 的一些底层细节和注意事项.写这篇文 ...

  9. JAVA中的变量及取值范围

    字节是二进制数据的单位.一个字节通常8位长.但是,一些老型号计算机结构使用不同的长度.为了避免混乱,在大多数国际文献中,使用词代替byte.变量: 变量的数据类型:变量名=变量值 数据类型 基本型 数 ...

  10. day15 Pyhton学习

    迭代器 掌握for循环 实际上for循环的本质,就是将一个可迭代的变成迭代器 每一次从中取值都相当于执行了一次next 如果是迭代器,那么只能取一次值 生成器 - 本质就是迭代器 生成器函数(返回值是 ...