Go/Python 异步桥
Go/Python asynchronous bridge
我写了一个客户端来处理较低级别的 TLS 连接参数,如 ClientHellos 等
我是用 Go 做的,因为它更容易。我的主要程序 (webscraper) 在 Python。我通过 ctypes 通过 DLL 将 Go 源连接到我的 Python 文件。到目前为止,我的网络爬虫结构是异步的,一次处理多个连接。
不幸的是,我的 Go 客户端不是异步的。有没有一种方法可以在 Python 中更改它,以便它异步等待来自 ctypes 指针的响应,直到它出现为止?现在它正在等待响应,但同时显然会阻止所有其他代码执行。
编辑:
下面的代码示例
async def request(self, method, url, headers, body=None, rawBody=None, pseudoHeaderOrder=["method", "authority", "scheme", "path"]):
global httpLib
global initFunc
global requestFunc
global changeProxyFunc
global freePointerFunc
config = {
"id": self.cid,
"method": method.upper(),
"timeout": 20000,
"url": url,
"pseudoHeaderOrder": pseudoHeaderOrder,
"headers": headers
}
#Critical
if body:
config["body"] = body
if rawBody:
rawBody = [b for b in bytes(rawBody, "utf-8")]
config["rawBody"] = rawBody
config = json.dumps(config)
#print(config)
#THIS PART CASTS THE REQUEST
ptr = requestFunc(config.encode('utf-8'))
string = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
#THIS PART CLEARS THE POINTER
freePointerFunc(ptr)
#...
您可以使用 executor.
将阻塞调用移动到单独的 thread/process
像这样的东西应该有用,
async def request(self, method, url, headers, body=None, rawBody=None, pseudoHeaderOrder=["method", "authority", "scheme", "path"]):
global httpLib
global initFunc
global requestFunc
global changeProxyFunc
global freePointerFunc
config = {
"id": self.cid,
"method": method.upper(),
"timeout": 20000,
"url": url,
"pseudoHeaderOrder": pseudoHeaderOrder,
"headers": headers
}
#Critical
if body:
config["body"] = body
if rawBody:
rawBody = [b for b in bytes(rawBody, "utf-8")]
config["rawBody"] = rawBody
config = json.dumps(config)
# Move blocking code to separate function
def blocking_io():
ptr = requestFunc(config.encode('utf-8'))
string = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
freePointerFunc(ptr)
return string
# Aschronously wait on the result
loop = asyncio.get_running_loop()
string = await loop.run_in_executor(None, blocking_io)
#...
我写了一个客户端来处理较低级别的 TLS 连接参数,如 ClientHellos 等
我是用 Go 做的,因为它更容易。我的主要程序 (webscraper) 在 Python。我通过 ctypes 通过 DLL 将 Go 源连接到我的 Python 文件。到目前为止,我的网络爬虫结构是异步的,一次处理多个连接。
不幸的是,我的 Go 客户端不是异步的。有没有一种方法可以在 Python 中更改它,以便它异步等待来自 ctypes 指针的响应,直到它出现为止?现在它正在等待响应,但同时显然会阻止所有其他代码执行。
编辑: 下面的代码示例
async def request(self, method, url, headers, body=None, rawBody=None, pseudoHeaderOrder=["method", "authority", "scheme", "path"]):
global httpLib
global initFunc
global requestFunc
global changeProxyFunc
global freePointerFunc
config = {
"id": self.cid,
"method": method.upper(),
"timeout": 20000,
"url": url,
"pseudoHeaderOrder": pseudoHeaderOrder,
"headers": headers
}
#Critical
if body:
config["body"] = body
if rawBody:
rawBody = [b for b in bytes(rawBody, "utf-8")]
config["rawBody"] = rawBody
config = json.dumps(config)
#print(config)
#THIS PART CASTS THE REQUEST
ptr = requestFunc(config.encode('utf-8'))
string = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
#THIS PART CLEARS THE POINTER
freePointerFunc(ptr)
#...
您可以使用 executor.
将阻塞调用移动到单独的 thread/process像这样的东西应该有用,
async def request(self, method, url, headers, body=None, rawBody=None, pseudoHeaderOrder=["method", "authority", "scheme", "path"]):
global httpLib
global initFunc
global requestFunc
global changeProxyFunc
global freePointerFunc
config = {
"id": self.cid,
"method": method.upper(),
"timeout": 20000,
"url": url,
"pseudoHeaderOrder": pseudoHeaderOrder,
"headers": headers
}
#Critical
if body:
config["body"] = body
if rawBody:
rawBody = [b for b in bytes(rawBody, "utf-8")]
config["rawBody"] = rawBody
config = json.dumps(config)
# Move blocking code to separate function
def blocking_io():
ptr = requestFunc(config.encode('utf-8'))
string = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
freePointerFunc(ptr)
return string
# Aschronously wait on the result
loop = asyncio.get_running_loop()
string = await loop.run_in_executor(None, blocking_io)
#...