真难以自信,使用Python强大的类库,可以用这么简短的代码就写好一个本地的HTTP代理!
真难以自信,这是我用Python花了连续6个小时写的第一个程序(之前写的一个Hello world除外)!
真难以自信,我就这样爱上了Python……
所以,以后在我博客上估计会有不少Python代码了……
现在我使用Python仍然停留在Thinking In The C++ Way而不是Thinking In The Python Way,所以最近会打算看一些Python类库里面的代码,看看别人是如何写的。
一开始使用Python3.2编写这个代理服务器,后来移植到Python2.7上去,这两个版本的差异还真的挺大的,我记得移植的时候改了不少地方。
我用py2exe编译了不需要Python运行环境的Windows可执行文件版本,方便大家测试,貌似编译之后比较臃肿。
这里有一篇关于如何使用py2exe编译python脚本的文章:
www.cnblogs.com/jans2002/archive/2006/09/30/519393.html
下载地址:sogouproxy win32
Python源代码:
'''
Hey guys!
This is a the first python program(except hello worlds) I have written.
With HTTPServer, I can easily write a webserver.
Python is such a powerful language that many complicated problems can be
solved by a few lines of code.
Welcome to visit my blog: www.xiaoxia.org
The proxy program is just coded for fun :-)
'''
from threading import Thread
from struct import unpack
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from httplib import HTTPResponse
from SocketServer import ThreadingMixIn
import socket
import time, sys, random
x_sogou_auth = "9CD285F1E7ADB0BD403C22AD1D545F40/30/853edc6d49ba4e27"
proxy_host = "h0.cnc.bj.ie.sogou.com"
proxy_port = 80
def calc_sogou_hash(t, host):
s = (t + host + 'SogouExplorerProxy').encode('ascii')
code = len(s)
dwords = int(len(s)/4)
rest = len(s) % 4
v = unpack(str(dwords) + 'i'+str(rest)+'s', s)
for vv in v:
if(type(vv)==type('i')):
break
a = (vv & 0xFFFF)
b = (vv >> 16)
code += a
code = code ^ (((code<<5)^b) << 0xb)
# To avoid overflows
code &= 0xffffffff
code += code >> 0xb
if rest == 3:
code += ord(s[len(s)-2]) * 256 + ord(s[len(s)-3])
code = code ^ ((code ^ (ord(s[len(s)-1])*4)) << 0x10)
code &= 0xffffffff
code += code >> 0xb
elif rest == 2:
code += ord(s[len(s)-1]) * 256 + ord(s[len(s)-2])
code ^= code << 0xb
code &= 0xffffffff
code += code >> 0x11
elif rest == 1:
code += ord(s[len(s)-1])
code ^= code << 0xa
code &= 0xffffffff
code += code >> 0x1
code ^= code * 8
code &= 0xffffffff
code += code >> 5
code ^= code << 4
code = code & 0xffffffff
code += code >> 0x11
code ^= code << 0x19
code = code & 0xffffffff
code += code >> 6
code = code & 0xffffffff
return hex(code)[2:].rstrip('L').zfill(8)
class Handler(BaseHTTPRequestHandler):
s = 0
def do_proxy(self):
try:
if self.s == 0:
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.connect((proxy_host, proxy_port))
self.s.send(self.requestline.encode('ascii') + b"\r\n")
# Add Sogou Verification Tags
self.headers["X-Sogou-Auth"] = x_sogou_auth
t = hex(int(time.time()))[2:].rstrip('L').zfill(8)
self.headers["X-Sogou-Tag"] = calc_sogou_hash(t, self.headers['Host'])
self.headers["X-Sogou-Timestamp"] = t
self.s.send(str(self.headers).encode('ascii') + b"\r\n")
# Send Post data
if(self.command=='POST'):
self.s.send(self.rfile.read(int(self.headers['Content-Length'])))
response = HTTPResponse(self.s, method=self.command, buffering=True)
response.begin()
# Reply to the browser
status = "HTTP/1.1 " + str(response.status) + " " + response.reason
self.wfile.write(status.encode('ascii') + b'\r\n')
h = ''
for hh, vv in response.getheaders():
if hh.upper()!='TRANSFER-ENCODING':
h += hh + ': ' + vv + '\r\n'
self.wfile.write(h.encode('ascii') + b'\r\n')
while True:
response_data = response.read(8192)
if(len(response_data) == 0):
break
self.wfile.write(response_data)
except socket.error:
print('socket error for ' + self.requestline)
def do_POST(self):
self.do_proxy()
def do_GET(self):
self.do_proxy()
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
pass
server = ThreadingHTTPServer(("127.0.0.1", 1998), Handler)
#print(calc_sogou_hash('4d8cdaed', 'www.youku.com'))
print('Please select your network:\n\
1. CERNET(The China Education and Research Network)\n\
2. CTCNET(China Telecommunications Corporation)\n\
3. CNCNET(China NetCom)\n\
4. DXT(Dian Xin Tong)\n')
i = int(input('Input the number: '))
if i==1:
proxy_host = 'h' + str(random.randint(0,10)) + '.edu.bj.ie.sogou.com'
elif i==2:
proxy_host = 'h' + str(random.randint(0,3)) + '.ctc.bj.ie.sogou.com'
elif i==3:
proxy_host = 'h' + str(random.randint(0,3)) + '.cnc.bj.ie.sogou.com'
elif i==4:
proxy_host = 'h' + str(random.randint(0,10)) + '.dxt.bj.ie.sogou.com'
print('Proxy over ' + proxy_host)
server.serve_forever()
py2exe 不能直接用在py3.x吧.
嗯,是的!所以我还是转2.7了。我的Ubuntu上的版本是2.6.6
你终于还是转向了Python 。哈哈。
😀
你好像很了解我的样子
又多了个pythoner~~……像你原来提到过的notify用python的话就几行
另,我觉得最后那段写到main里会好些
嗯,你说的有道理!!!
py有它的好处,代码风格很好,代码量少。就是那些库学起来费力。
官方有库的手册,网上也有很多实例代码,用起来还是挺方便的。
而且,我也经常去翻库函数的代码看,看一下它的代码实现就更好了。
Python的标准库的代码阅读起来很爽,比起C++的STL代码,更好看,更易懂啊!
现在你贴的代码一闪而过!就看到Hi guys然后就闪没了
什么浏览器? 是googlesyntaxhighlighter的bug?
360浏览器跟IE显示不了,FireFox表示可以看到
原来360浏览器是能看到的,嗯
这里的“原来”可能会有歧义,so我改成“以前”
好像就是IE core的浏览器看不了Python的代码!!!
哈哈,要看代码,大家都用Firefox或者Chrome吧……
Hi,小虾,你好。
我在一个程序中使用到了你的代理程序。
请参阅:
http://www.lijiejie.com/article/Works/Npu_Browser_V_1.0.3.htm
直接打包了你的程序。 这是我的QQ : 9182263
可以的!但是,仅供学习研究好了哦,别用在商业上去。
表示fedora的yum就是用python写的……
个人虽然喜欢python,但是还是喜欢c/vala 更多吧(对解释型无爱)
写代理服务器应该性能要求更大吧
对,如果要做出产品给用户使用的话,为了满足性能上的需求,还是C/C++比较实际。
Python方便我写测试代码。
被小虾扒皮了,杯具的搜狗是不是又得换协议了?哈哈
是难以置信。。。。
嗯,我也发现了!!!
楼主,你的软件编的真的很好啊。有一个问题,为什么用了你的代理后,打不开qq邮箱之类的?
这个代理程序没有写CONNECT的命令,所以不支持https连接,你可以完善一下程序。
真难以置信,我想在linux下不用wine使用sogou代理的多年夙愿就这样实现了!
真难以置信,还是用我最爱的python写的!
真难以置信,楼主还是hello world之后就写了这个!!!
…果断订阅小虾的rss!!
泪流满面,妈妈再也不用担心我在教育网下用linux和mac os x上不了各种网站了…谢谢谢谢楼主!!!
xiaoxia大大能不能完善一下?没有https连接好痛苦…
好的,我尽量抽时间来弄弄咯。。。
华南理工大学的吗?
不是…西交…虽然有ipv6什么的但是速度很慢 之前开着虚拟机就是为了各种代理 蛋疼TAT
怎么貌似用不了呢?
可以的啊,我今晚用了一下。选择1使用教育网。
我一运行,Gnome的截图程序就跑出来了,然后就自动退出了,不知道咋回事
你怎么运行的呀?
例如保存为proxy.py。
在终端里,输入
root@xiaoxia-pc:~# python proxy.py 回车。
显示如下:
root@xiaoxia-pc:~# python proxy.py
Please select your network:
1. CERNET(The China Education and Research Network)
2. CTCNET(China Telecommunications Corporation)
3. CNCNET(China NetCom)
4. DXT(Dian Xin Tong)
Input the number: 1
Proxy over h3.edu.bj.ie.sogou.com
Pingback引用通告: Python写简单的网络服务器示例 « Xiaoxia[PG]
Pingback引用通告: Linux下独立使用搜狗浏览器代理 | Ernest's Blog
对很多非https的网站 也不能登录啊
登录用到了https了吧!!!我周一或周二发一个完美支持https的sogou代理版本,关注我的文章哈哈。
需要在浏览器代理中设置127.0.0.1本地代理吗
是的,HTTP的!
Pingback引用通告: 用Python写的本地Sogou代理服务器程序 | 核桃薄壳