socket模块
Fiddler工具HTTP抓包的原理就是设置本地代理然后,获取请求报文—转发报文----获取服务器返回值—请求报文…的一系列操作,前提是设置浏览器的本地代理IP和端口号,一般代理IP都设置为127.0.0.1,端口为8080。IE浏览器中设置代理位置:Internet选项----连接----局域网设置–取消自动检测设置和使用自动配置脚本—勾选“为LAN代理服务器” 并填写地址IP+Port。IE浏览器设置过后便会在本地只要有HTTP/HTTPS请求都要通过这个代理。
## 自动设置本地请求代理IP和端口
```python
import winreg#为操作注册表的库
def disableProxy(proxy):
proxy = ""
xpath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings"
try:
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, xpath, 0, winreg.KEY_WRITE)
winreg.SetValueEx(key, "ProxyEnable", 0, winreg.REG_DWORD, 0)
winreg.SetValueEx(key, "1ProxyServer", 0, winreg.REG_SZ, proxy)
except Exception as e:
print("ERROR: " + str(e.args))
finally:
None
proxy=ip+":"+port
disableProxy(proxy)
**winreg*
*读取用的方法是OpenKey方法:打开特定的key
_winreg.OpenKey(key,sub_key,res=0,sam=KEY_READ)
socket模块中有几个函数
server=socket.socket()-----创建套接字
server.bind(("127.0.0.1",8000))----绑定本地这个IP和端口
server.listen(3)------等待客户端连接(这里的客户端是值本地PC所有HTTP请求中都会先到这儿)
c,addr=server.accept()-----建立客户端连接 返回connection 对象 表示已连接到客户端。
while true:
c..recv(1024)--接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
c.sendall(msg)--- 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
```python
import socket
import thread
import urlparse
import select
BUFLEN=8192
class Proxy(object):
def __init__(self,conn,addr):
self.source=conn
self.request=""
self.headers={}
self.destnation=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.run()
def get_headers(self):#获取头部信息
header=''
while True:
header+=self.source.recv(BUFLEN)
print header
index=header.find('\n')
if index >0:
break
#firstLine,self.request=header.split('\r\n',1)
print "header"
print header
firstLine=header[:index]
self.request=header[index+1:]
self.headers['method'],self.headers['path'],self.headers['protocol']=firstLine.split()
def conn_destnation(self):
url=urlparse.urlparse(self.headers['path'])
hostname=url[1]
port="80"
if hostname.find(':') >0:
addr,port=hostname.split(':')
else:
addr=hostname
port=int(port)
ip=socket.gethostbyname(addr)
print ip,port
try:
self.destnation.connect((ip, port))# 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
data = "%s %s %s\r\n" % (self.headers['method'], self.headers['path'], self.headers['protocol'])
self.destnation.send(data + self.request)#发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
print "data" + "\n", data
print "request" + "\n", self.request
except Exception as e :
print e.message
pass
def renderto(self):
readsocket=[self.destnation]
while True:
data=''
(rlist,wlist,elist)=select.select(readsocket,[],[],3)#第一个参数是我们需要监听可读的套接字, 第二个参数是我们需要监听可写的套接字, 第三个参数使我们需要监听异常的套接字, 第四个则是时间限制设置.
if rlist:
data=rlist[0].recv(BUFLEN)#接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
if len(data)>0:
self.source.send(data)
else:
break
def run(self):
self.get_headers()
self.conn_destnation()
self.renderto()
class Server(object):
def __init__(self,host,port,handler=Proxy):
self.host=host
self.port=port
self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((host,port))
self.server.listen(5)
self.handler=handler
def start(self):
while True:
try:
conn,addr=self.server.accept()
thread.start_new_thread(self.handler,(conn,addr))
except:
pass
if __name__=='__main__':
s=Server('127.0.0.1',5055)
s.start()