【问题标题】:Accessing Popen web server from Python script on Linux在 Linux 上从 Python 脚本访问 Popen Web 服务器
【发布时间】:2021-03-10 07:10:10
【问题描述】:

我有这个脚本并尝试在 CentOS 7 上运行它(尽管我相当确定发行版并不重要):

from subprocess import Popen, DEVNULL
from urllib import request

p = Popen(['python', '-m', 'http.server'], cwd='.', stderr=DEVNULL, stdout=DEVNULL)
try:
   r = request.urlopen('http://localhost:8000')
   print(r.read())
finally:
   p.terminate()
   p.wait()

我知道Popen 原则上是正确的,因为如果我运行这个脚本,我可以从服务器读取类似curl localhost:8000 的内容:

from subprocess import Popen, DEVNULL
from urllib import request
from time import sleep

p = Popen(['python', '-m', 'http.server'], cwd='.', stderr=DEVNULL, stdout=DEVNULL)
try:
   sleep(30)
finally:
   p.terminate()
   p.wait()

我也知道.urlopen() 命令应该可以工作,因为我可以从命令行运行类似的 Web 服务器,然后打开交互式 Python 会话并运行相同的两行:

r = request.urlopen('http://localhost:8000')
print(r.read())

它会打印预期的页面。

我的问题:为什么运行第一个脚本会导致连接错误?

具体来说,我收到以下错误:

Traceback (most recent call last):
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 1342, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/http/client.py", line 1255, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/http/client.py", line 1301, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/http/client.py", line 1250, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/http/client.py", line 1010, in _send_output
    self.send(msg)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/http/client.py", line 950, in send
    self.connect()
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/http/client.py", line 921, in connect
    self.sock = self._create_connection(
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/socket.py", line 843, in create_connection
    raise err
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/socket.py", line 831, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jaap.vandervelde/sandbox/run.py", line 6, in <module>
    r = request.urlopen('http://localhost:8000')
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 517, in open
    response = self._open(req, data)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 534, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 1371, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/home/jaap.vandervelde/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 1345, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 111] Connection refused>

我觉得我错过了一些明显的东西,但我没有看到它。更是如此,因为完全相同的脚本在 Windows 上运行时会产生预期的结果。

请注意,我不打算用上面的代码运行任何重要的东西,我只是在某个旧的单元测试中放置了类似的东西,无法弄清楚为什么它不能在这个平台上运行。

【问题讨论】:

    标签: python linux urllib popen


    【解决方案1】:

    您需要等待。您无法保证 Web 服务器已自行初始化并在您发出请求时准备好为请求提供服务。

    【讨论】:

    • 可能是这样 - 等待任意时间似乎是一种浪费,我想轮询服务直到它可能有路要走......(捕获异常直到它成功,或者一段时间后失败)
    猜你喜欢
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 2018-10-15
    • 1970-01-01
    • 2017-07-25
    相关资源
    最近更新 更多