- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个脚本(多线程)来从网站检索内容,并且该网站不是很稳定,所以时不时会有挂起的 http 请求,甚至无法通过 socket.setdefaulttimeout 超时()
。由于我无法控制该网站,我唯一能做的就是改进我的代码,但我现在已经没有想法了。
示例代码:
socket.setdefaulttimeout(150)
MechBrowser = mechanize.Browser()
Header = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1 (.NET CLR 3.5.30729)'}
Url = "http://example.com"
Data = "Justatest=whatever&letstry=doit"
Request = urllib2.Request(Url, Data, Header)
Response = MechBrowser.open(Request)
Response.close()
如何强制退出挂起的请求?其实我想知道为什么 socket.setdefaulttimeout(150)
首先不工作。任何人都可以帮助我吗?
已添加:(是的,问题仍未解决)
好的,我听从了 tomasz 的建议并将代码更改为 MechBrowser.open(Request, timeout = 60)
,但同样的事情发生了。直到现在我仍然随机收到挂起请求,有时是几个小时,有时可能是几天。现在我该怎么做?有没有办法强制这些挂起的请求退出?
最佳答案
虽然 socket.setsocketimeout
将为新套接字设置默认超时,但如果您不直接使用套接字,则可以轻松覆盖该设置。特别是,如果库在其套接字上调用 socket.setblocking
,它将重置超时。
urllib2.open
有一个超时参数,但是urllib2.Request
没有超时参数。当您使用 mechanize
时,您应该引用他们的文档:
Since Python 2.6, urllib2 uses a .timeout attribute on Request objects internally. However, urllib2.Request has no timeout constructor argument, and urllib2.urlopen() ignores this parameter. mechanize.Request has a timeout constructor argument which is used to set the attribute of the same name, and mechanize.urlopen() does not ignore the timeout attribute.
来源:http://wwwsearch.sourceforge.net/mechanize/documentation.html
---编辑---
如果 socket.setsockettimeout
或将超时传递给 mechanize
可以使用较小的值,但不能使用较高的值,则问题的根源可能完全不同。一件事是你的图书馆可能会打开多个连接(这里归功于@Cédric Julien),所以超时适用于 socket.open 的每一次尝试,如果它没有因第一次失败而停止 - 可能需要 timeout * num_of_conn
秒。另一件事是 socket.recv
:如果连接真的很慢而且你够倒霉,整个请求可能会占用 timeout * incoming_bytes
就像每个 socket.recv
我们可以获得一个字节,并且每次这样的调用都可能需要 timeout
秒。由于您不太可能遭受这种黑暗场景的影响(每个超时秒一个字节?您必须是一个非常粗鲁的男孩),很可能会要求花费很长时间才能实现非常慢的连接和非常高的超时。
唯一的解决办法是强制整个请求超时,但这里与套接字无关。如果您使用的是 Unix,则可以使用带有 ALARM
信号的简单解决方案。您将信号设置为在 timeout
秒后发出,您的请求将被终止(不要忘记捕获它)。您可能喜欢使用 with
语句来使其简洁易用,例如:
import signal, time
def request(arg):
"""Your http request"""
time.sleep(2)
return arg
class Timeout():
"""Timeout class using ALARM signal"""
class Timeout(Exception): pass
def __init__(self, sec):
self.sec = sec
def __enter__(self):
signal.signal(signal.SIGALRM, self.raise_timeout)
signal.alarm(self.sec)
def __exit__(self, *args):
signal.alarm(0) # disable alarm
def raise_timeout(self, *args):
raise Timeout.Timeout()
# Run block of code with timeouts
try:
with Timeout(3):
print request("Request 1")
with Timeout(1):
print request("Request 2")
except Timeout.Timeout:
print "Timeout"
# Prints "Request 1" and "Timeout"
如果想要比这更便携,你必须使用一些更大的枪,例如 multiprocessing
,所以你会产生一个进程来调用你的请求并在逾期时终止它。由于这将是一个单独的进程,您必须使用某些东西将结果传回您的应用程序,它可能是 multiprocessing.Pipe
。例子来了:
from multiprocessing import Process, Pipe
import time
def request(sleep, result):
"""Your http request example"""
time.sleep(sleep)
return result
class TimeoutWrapper():
"""Timeout wrapper using separate process"""
def __init__(self, func, timeout):
self.func = func
self.timeout = timeout
def __call__(self, *args, **kargs):
"""Run func with timeout"""
def pmain(pipe, func, args, kargs):
"""Function to be called in separate process"""
result = func(*args, **kargs) # call func with passed arguments
pipe.send(result) # send result to pipe
parent_pipe, child_pipe = Pipe() # Pipe for retrieving result of func
p = Process(target=pmain, args=(child_pipe, self.func, args, kargs))
p.start()
p.join(self.timeout) # wait for prcoess to end
if p.is_alive():
p.terminate() # Timeout, kill
return None # or raise exception if None is acceptable result
else:
return parent_pipe.recv() # OK, get result
print TimeoutWrapper(request, 3)(1, "OK") # prints OK
print TimeoutWrapper(request, 1)(2, "Timeout") # prints None
如果你想强制请求在固定的秒数后终止,你真的没有太多选择。 socket.timeout
将为单个套接字操作(连接/接收/发送)提供超时,但如果您有多个套接字操作,则执行时间可能会很长。
关于python - 如果 socket.setdefaulttimeout() 不起作用怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8464391/
基于 socket.io 的官方网站 http://socket.io/#how-to-use , 我找不到任何术语。socket.emit 、 socket.on 和 socket.send 之间有
我正在使用 lua-socket 3.0rc1.3(Ubuntu Trusty 附带)和 lua 5.1。我正在尝试监听 unix 域套接字,我能找到的唯一示例代码是 this -- send std
这两者有什么区别? 我注意到如果我在一个工作程序中从 socket.emit 更改为 socket.send ,服务器无法接收到消息,虽然我不明白为什么。 我还注意到,在我的程序中,如果我从 sock
使用套接字在两台服务器之间发送数据是个好主意,还是应该使用 MQ 之类的东西来移动数据。 我的问题:套接字是否可靠,如果我只需要一次/有保证的数据传输? 还有其他解决方案吗? 谢谢。 最佳答案 套接字
引自 this socket tutorial : Sockets come in two primary flavors. An active socket is connected to a
我已经安装了在端口81上运行的流服务器“Lighttpd”(light-tpd)。 我有一个C程序,它使用套接字api创建的服务器套接字在端口80上监听http请求。 我希望从客户端收到端口80上的请
这是我正在尝试做的事情: 当有新消息可用时,服务器会将消息发送给已连接的客户端。另一方面,客户端在连接时尝试使用send()向服务器发送消息,然后使用recv()接收消息,此后,客户端调用close(
如何将消息发送到动态 session 室,以及当服务器收到该消息时,如何将该消息发送到其他成员所在的同一个 session 室? table_id是房间,它将动态设置。 客户: var table_i
这是我尝试但不起作用的方法。我可以将传入的消息从WebSocket连接转发到NetSocket,但是只有NetSocket收到的第一个消息才到达WebSocket后面的客户端。 const WebSo
我正在实现使用boost将xml发送到客户端的服务器。我面临的问题是缓冲区不会立即发送并累积到一个点,然后发送整个内容。这在我的客户端造成了一个问题,当它解析xml时,它可能具有不完整的xml标记(不
尝试使用Nginx代理Gunicorn套接字。 /etc/systemd/system/gunicorn.service文件 [Unit] Description=gunicorn daemon Af
我正在使用Lua套接字和TCP制作像聊天客户端和服务器这样的IRC。我要弄清楚的主要事情是如何使客户端和服务器监听消息并同时发送它们。由于在服务器上执行socket:accept()时,它将暂停程序,
我看了一下ZMQ PUSH/PULL套接字,尽管我非常喜欢简单性(特别是与我现在正在通过UDP套接字在系统中实现的自定义碎片/ack相比),但我还是希望有自定义负载平衡功能,而不是幼稚的回合-robi
我正在编写一个应用程序,其中有多个 socket.io 自定义事件,并且所有工作正常,除了这个: socket.on("incomingImg", function(data) {
在我的应用程序中,我向服务器发送了两条小消息(类似 memcached 的服务)。在类似 Python 的伪代码中,这看起来像: sock.send("add some-key 0") ignored
很抱歉再次发布此问题,但大多数相关帖子都没有回答我的问题。我在使用 socket.io 的多个连接时遇到问题我没有使用“socket.socket.connect”方法,但我从第一次连接中得到了反馈。
我尝试使用 socket.io 客户端连接到非 socket.io websocket 服务器。但我做不到。我正在尝试像这样连接到套接字服务器: var socket = io.connect('ws
我遇到了一个奇怪的问题。在我非常基本的服务器中,我有: server.listen(8001); io.listen(server); var sockets = io.sockets; 不幸的是,套
我正在使用带套接字 io 的sailsjs。帆的版本是 0.10.5。我有以下套接字客户端进行测试: var socketIOClient = require('socket.io-client');
这个问题在这里已经有了答案: What is the fundamental difference between WebSockets and pure TCP? (4 个答案) 关闭 4 年前。
我是一名优秀的程序员,十分优秀!