如何从Python脚本中杀死SimpleHTTPServer?

如何从Python脚本中杀死SimpleHTTPServer?,python,python-requests,simplehttpserver,Python,Python Requests,Simplehttpserver,我试图使用http.server测试Python项目中的所有链接。如果在运行脚本之前启动服务器,然后在关闭终端窗口时服务器停止,则可以使脚本正常工作。但是我真的希望脚本本身能够启动和停止服务器 我制作了一个测试脚本,只需启动服务器,获取一个页面并证明服务器正在运行,然后停止服务器。我似乎无法获取服务器的pid。当我试图在脚本运行后终止该脚本报告的pid时,我收到一条消息,表示没有这样的进程;但服务器仍在运行 如何为服务器获取正确的pid,或者更一般地说,如何从脚本中停止服务器 import os

我试图使用
http.server
测试Python项目中的所有链接。如果在运行脚本之前启动服务器,然后在关闭终端窗口时服务器停止,则可以使脚本正常工作。但是我真的希望脚本本身能够启动和停止服务器

我制作了一个测试脚本,只需启动服务器,获取一个页面并证明服务器正在运行,然后停止服务器。我似乎无法获取服务器的pid。当我试图在脚本运行后终止该脚本报告的pid时,我收到一条消息,表示没有这样的进程;但服务器仍在运行

如何为服务器获取正确的pid,或者更一般地说,如何从脚本中停止服务器

import os
import requests
from time import sleep

# Start server, in background.
print("Starting server...")
os.system('python -m http.server &')
# Make sure server has a chance to start before making request.
sleep(1)

print "Server pid: "
os.system('echo $$')

url = 'http://localhost:8000/index.html'
print("Testing request: ", url)
r = requests.get(url)
print("Status code: ", r.status_code)

以下是我正在做的:

import threading

try: 
    from http.server import HTTPServer, SimpleHTTPRequestHandler # Python 3
except ImportError: 
    from SimpleHTTPServer import BaseHTTPServer
    HTTPServer = BaseHTTPServer.HTTPServer
    from SimpleHTTPServer import SimpleHTTPRequestHandler # Python 2

server = HTTPServer(('localhost', 0), SimpleHTTPRequestHandler)
thread = threading.Thread(target = server.serve_forever)
thread.daemon = True
thread.start()

def fin():
    server.shutdown()

print('server running on port {}'.format(server.server_port))

# here is your program

如果您在程序中调用
fin
,则服务器将关闭。

我让它运行,但我很想知道这与上面用户的答案相比如何。我是在看了公认的答案后得出这个结论的


对上述用户代码稍作修改:

import threading
try: 
  from http.server import HTTPServer, BaseHTTPRequestHandler # Python 3
except ImportError: 
  import SimpleHTTPServer
  from BaseHTTPServer import HTTPServer # Python 2
  from SimpleHTTPServer import SimpleHTTPRequestHandler as BaseHTTPRequestHandler
server = HTTPServer(('localhost', 0), BaseHTTPRequestHandler)
thread = threading.Thread(target = server.serve_forever)
thread.deamon = True
def up():
  thread.start()
  print('starting server on port {}'.format(server.server_port))
def down():
  server.shutdown()
  print('stopping server on port {}'.format(server.server_port))

我的浏览器打开解决方案:

文件:http.py

导入SimpleHTTPServer
导入SocketServer
导入线程
导入网络浏览器
导入平台
从socket导入SOL\u socket,因此
类HTTPServer():
def _uinit _;(self,port=8000,url=8000)http://localhost'):
self.port=端口
self.thread=None
self.httpd=None
self.run=False
self.url=url
os=platform.system()
如果os==“Linux”:
self.browser_path=“/usr/bin/google chrome%s”
elif os==“Windows”:
self.browser_path=“C:/Program Files(x86)/Google/Chrome/Application/Chrome.exe%s”
其他:
打印(“未找到Chrome!”)
def启动(自):
self.run=True
self.httpd=SocketServer.TCPServer((“”,self.port),SimpleHTTPServer.simplehttpprequesthandler)
self.httpd.socket.setsockopt(SOL_socket,SO_REUSEADDR,1)
self.thread=threading.thread(target=self.\u serve)
self.thread.start()
webbrowser.get(str(self.browser_path)).open(self.url+“:”+str(self.port)+“/”)
def_serve(自助式):
自运行时:
self.httpd.handle_请求()
def停止(自):
self.run=False
self.httpd.server_close()
之后,只需运行:

从http导入HTTPServer
server=HTTPServer()
server.start()
原始输入(“输入以关闭”)
server.stop()

这是问题的一个解决方案。在Python3上工作

import os
import threading
import webbrowser
from http.server import HTTPServer, SimpleHTTPRequestHandler


def simple_http_server(host='localhost', port=4001, path='.'):

    server = HTTPServer((host, port), SimpleHTTPRequestHandler)
    thread = threading.Thread(target=server.serve_forever)
    thread.deamon = True

    cwd = os.getcwd()

    def start():
        os.chdir(path)
        thread.start()
        webbrowser.open_new_tab('http://{}:{}'.format(host, port))
        print('starting server on port {}'.format(server.server_port))

    def stop():
        os.chdir(cwd)
        server.shutdown()
        server.socket.close()
        print('stopping server on port {}'.format(server.server_port))

    return start, stop
simple\u http\u服务器
将返回
start
stop
功能

>>> start, stop = simple_http_server(port=4005, path='/path/to/folder')
你可以把它当作

>>> start()
starting server on port 4005

127.0.0.1 - - [14/Aug/2016 17:49:31] "GET / HTTP/1.1" 200 -

>>> stop()
stopping server on port 4005

在我看来,我所做的是:

  • 转到活动监视器
  • 然后进入网络
  • 搜索单词“python”
  • (仅当您在python中运行cmd/terminal命令时,因为我认为在cmd/terminal中停止该命令的方法是ctrl+c或退出cmd/terminal)

    注意:pid也存在

  • 退出进程“python”(如果没有,请使用force退出进程)
  • 如果这在cmd/terminal中有效,那么您就完成了!恩乔伊~
  • 希望这有帮助:D

    使用Python 3.8

    import http.server
    import socketserver
    import threading
    PORT = 8000
    Handler = http.server.SimpleHTTPRequestHandler
    server = socketserver.TCPServer(("", PORT), Handler)
    thread = threading.Thread(target = server.serve_forever)
    thread.daemon = True
    thread.start()
    

    这是一个上下文风格的版本,我更喜欢它,因为它会自动清理,您可以指定要提供服务的目录:

    from contextlib import contextmanager
    from functools import partial
    from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
    from threading import Thread
    
    
    @contextmanager
    def http_server(host: str, port: int, directory: str):
        server = ThreadingHTTPServer(
            (host, port), partial(SimpleHTTPRequestHandler, directory=directory)
        )
        server_thread = Thread(target=server.serve_forever, name="http_server")
        server_thread.start()
    
        try:
            yield
        finally:
            server.shutdown()
            server_thread.join()
    
    
    def usage_example():
        import time
    
        with http_server("127.0.0.1", 8087, "."):
            # now you can use the web server
            time.sleep(100)
    

    您可以使用
    subprocess.Popen
    而不是
    os.system
    ,它提供了许多附加功能,包括终止生成的子流程。或者您可以导入SimpleHTTPServer并直接在脚本中使用它……这很有帮助,但是您介意多说一点吗?我找到的关于使用SimpleHTTPServer的唯一参考资料是从命令行使用它;我不太确定如何在python脚本中停止和启动服务器。我以前也从未使用过进程,所以我不太确定如何启动服务器子进程,然后停止它。积极地谷歌搜索…有你需要的所有信息,请参阅关于
    Popen
    构造函数和使用
    Popen
    对象的部分-你可以做一些类似
    server=Popen([“python”、“-m”、“SimpleHTTPServer”])
    的事情,然后使用
    server.terminate()
    server.kill()
    来结束进程。至于在脚本中启动
    SimpleHTTPServer
    ,只需查看SimpleHTTPServer.py中的
    if\uuuuu name\uuuuu=“\uuuu main\uuuuu”:
    块-只需保留对BaseServer实例的引用并关闭它(它是一个TCPServer子类,所以TCPServer文档应该会有所帮助),但我也希望它能在Python3上运行。我收到一个错误“没有名为HTTPServer的模块”,因此我将python2导入从BaseHTTPServer导入HTTPServer更改为
    。导入工作正常,但随后我得到一个错误“\uuuu init\uuuuuu()得到了一个意外的关键字参数‘daemon’”。如果我使用这个脚本的我自己的版本,或者如果我只是复制你的脚本并修复导入,我就会得到这个。有什么建议吗?我加了一句话修正了执事的论点。这应该可以在Python3和Python2下工作了-希望如此。你能用Ctrl-C杀死服务器吗?@CiroSantilli巴拿馬文件六四事件法轮功 由于deamon设置为true,程序应该在主线程结束后完成。通常,主线程可以用Control+C终止。@User我没有在Ubuntu 16.04、Python 2.7、gnome终端上复制。在Ctrl+C上没有发生任何事情,服务器只是一直在运行,我必须关闭终端才能让它停止。你可以在Windows上使用
    start%s
    ,在OSX上使用
    open%s
    (Linux不确定)来打开默认浏览器,而不是打开Chrome。这是一种“内部”方法吗?我和你有同样的问题,所以我在google中搜索了什么是PID,并在google中显示了这样的结果:然后我有了一个放弃它的想法,然后它确实起作用了,你的方法是我
    from contextlib import contextmanager
    from functools import partial
    from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
    from threading import Thread
    
    
    @contextmanager
    def http_server(host: str, port: int, directory: str):
        server = ThreadingHTTPServer(
            (host, port), partial(SimpleHTTPRequestHandler, directory=directory)
        )
        server_thread = Thread(target=server.serve_forever, name="http_server")
        server_thread.start()
    
        try:
            yield
        finally:
            server.shutdown()
            server_thread.join()
    
    
    def usage_example():
        import time
    
        with http_server("127.0.0.1", 8087, "."):
            # now you can use the web server
            time.sleep(100)