1.需要了解知識
-
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()