Closed zenghh closed 1 year ago
有
最好还是直接走 Tab 的 DefaultCallback 吧. 你这是协程的么
不是协程, sync函数
要怎么做才能不遗漏呢,我发现应该是有遗漏掉部分消息
sync 部分我基本都不维护了, 缺点太多折腾不过来, 如果想监听所有事件, 可以魔改 Tab._recv_daemon
里面加上个默认回调应该就可以了
PS: 以前开源这套框架其实是因为没其他可用的, 我记得微软的 play Wright 也是支持同步和协程两套方案的, 可以考虑试一试, 虽然 puppeteer 作者都去了微软开发那个库, 但我看了下 python 版本的似乎只是调用了 node.js 的各类方法... 源码不是纯 python 的
sync 部分我基本都不维护了, 缺点太多折腾不过来, 如果想监听所有事件, 可以魔改
Tab._recv_daemon
里面加上个默认回调应该就可以了PS: 以前开源这套框架其实是因为没其他可用的, 我记得微软的 play Wright 也是支持同步和协程两套方案的, 可以考虑试一试, 虽然 puppeteer 作者都去了微软开发那个库, 但我看了下 python 版本的似乎只是调用了 node.js 的各类方法... 源码不是纯 python 的
我之前也用playwright,但是我要爬取的网站可以检测出来用自动化框架,所以借用下你的
呃... 好几个用了别的被检测跑来用我这个了... 我也没加屏蔽指纹之类的东西, 怪了. 你可以先猴子补丁覆盖下那个函数试试吧, 我也不确定会不会被检测到. 有啥问题随时交流
你的可以正常运行,还有你的async版本会有问题吗,能否接收到全部监听的websocket消息
大概我的只添加了几个比较简单的默认启动参数, 没加太多. 其实你直接魔改 tab 下面的 _recv_daemon 函数加上回调自己处理就可以的, 遗漏消息主要是 while 循环里等待是有间隔的, 魔改方法对动态语言来说也不麻烦
当然也可以不改源码试试, 你的代码里把回调函数去掉放到 filter_function 参数里面, 然后把超时开高, filter_function 里面一直返回 false 它就会一直收消息, 不过也不保证不丢消息...毕竟在循环里面是有空档的, 不如上面魔改
协程的一直在维护, 而且自带 Default Callback 方法, 当初弃用多线程主要还是多线程无法在外部杀死, 而且并发高起来以后 CPU 切换成本太高(有时候要维护集群里的远程 chrome)
主要asyncio不是太理解,所以只好用sync版本
没事, 先解决问题, 有空再看. 协程也不万能的, 要改整套架构都要改太费劲了, 一不小心还容易因为一个 CPU 秘籍任务阻塞主线程, 用多线程就不会.
早年间用 gevent 时候被一个 C 写的 mysql 库阻塞的整个服务都慢了十倍, 不熟悉还是不能轻易上
def wait_event(
self,
event="",
timeout=None,
callback_function=None,
filter_function=None,
wait_seconds=None,
):
"""ensure enable the method first, or will not listen any event."""
timeout = self.timeout if timeout is None else timeout
start_time = time.time()
while 1:
request = {"method": event}
result = self.recv(request, timeout=timeout)
timeout_break = wait_seconds and time.time(
) - start_time > wait_seconds
if timeout_break:
break
if result or timeout == 0:
if callable(filter_function):
if filter_function(result):
break
else:
break
return callback_function(result) if callable(
callback_function) else result
应该是wait_seconds 调高,然后filter_funciton 返回false吧
大概我的只添加了几个比较简单的默认启动参数, 没加太多. 其实你直接魔改 tab 下面的 _recv_daemon 函数加上回调自己处理就可以的, 遗漏消息主要是 while 循环里等待是有间隔的, 魔改方法对动态语言来说也不麻烦
这边能不能麻烦你把代码加上去,我好更新代码
from ichrome import Chrome, Tab
import json
import websocket
def _recv_daemon(self):
while self.ws.connected:
try:
data_str = self.ws.recv()
if not data_str:
continue
try:
data_dict = json.loads(data_str)
if not isinstance(data_dict, dict):
continue
except (TypeError, json.decoder.JSONDecodeError):
continue
callback(data_dict)
f = self._listener.find_future(data_dict)
if f:
f.set_result(data_str)
except (
websocket._exceptions.WebSocketConnectionClosedException,
websocket._exceptions.WebSocketTimeoutException,
ConnectionResetError,
):
break
def callback(data):
# 或者丢队列里去
print('自定义函数', data)
Tab._recv_daemon = _recv_daemon
chrome = Chrome()
tab = chrome.new_tab()
# 记着打开这个 domain, 否则看不到事件
tab.enable('Network')
tab.set_url('http://bing.com')
print(tab.title)
就这么魔改一下原来的函数就行了, 最近有点忙
谢谢
我这样使用的话,有没有可能websocket的消息遗漏处理