尝试构建Web服务器并读取html文件,类型错误:必须是str,而不是bytes

2024-04-20 06:40:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试用python3构建一个简单的web服务器。并在网上找到许多样本代码。在所有的示例中,它们都使用如下代码

file = open('index.html', 'r')
index_content += file.read()
file.close()

但当我在笔记本电脑上运行它时,它会返回

Traceback (most recent call last):
File "WebServer.py", line 28, in <module>
pic_content += file.read()
TypeError: must be str, not bytes

有谁能告诉我出了什么事,怎么处理? 如果运行良好,当我在浏览器中输入http://localhost:8000时,它应该会显示文本和图片。你知道吗

哦!/usr/bin/env python文件

#coding=utf-8

import socket
import re

HOST = ''
PORT = 8000

#Read index.html, put into HTTP response data
index_content = '''
    HTTP/1.x 200 ok
    Content-Type: text/html

    '''

file = open('index.html', 'r')
index_content += file.read()
file.close()

#Read picture, put into HTTP response data
file = open('Yoda.png', 'rb')
pic_content = '''
    HTTP/1.1 200 ok
    Content-Type: image/png

    '''
pic_content += file.read()
file.close()



#Configure socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(100)

#infinite loop
while True:
    # maximum number of requests waiting
    conn, addr = sock.accept()
    request = conn.recv(1024)
    method = request.split(' ')[0]
    src  = request.split(' ')[1]

    print ("Connect by: ", addr)
    print ("Request is:\n", request)

    #deal wiht GET method
    if method == 'GET':
        if src == '/index.html':
            content = index_content
        elif src == '/Yoda.png':
            content = pic_content
        elif re.match('^/\?.*$', src):
            entry = src.split('?')[1]      # main content of the request
            content = 'HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'
            content += entry
            content += '<br /><font color="green" size="7">register successs!</p>'
        else:
            continue


    #deal with POST method
    elif method == 'POST':
        form = request.split('\r\n')
        entry = form[-1]      # main content of the request
        content = '''HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'''
        content += entry
        content += '''<br /><font color="green" size="7">register successs!</p>'''

    ######
    # More operations, such as put the form into database
    # ...
    ######

    else:
        continue

    conn.sendall(content)

    #close connection
    conn.close()

这是本书的内容索引.html你知道吗

<!-- saved from url=(0054)http://www.cse.unsw.edu.au/~salilk/comp3331/index.html -->
<html class="cye-disabled cye-nm gr__cse_unsw_edu_au"><!--
Author: Yoda
Date:   A long time ago
URL:    http://www.cse.unsw.edu.au/~salilk/comp3331/index.html
--><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><style id="nightModeStyle">
html.cye-enabled.cye-nm:not(*:-webkit-full-screen) body,
 html.cye-enabled.cye-nm:not(*:-webkit-full-screen) #cye-workaround-body {-webkit-filter:contrast(91%) brightness(84%) invert(1);}</style><style id="cyebody">html.cye-enabled.cye-lm body{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style><style id="cyediv">html.cye-enabled.cye-lm div{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style><style id="cyetable">html.cye-enabled.cye-lm th{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}html.cye-enabled.cye-lm td{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style><style id="cyetextInput">html.cye-enabled.cye-lm input[type=text]{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}html.cye-enabled.cye-lm textarea{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style><style id="cyeselect">html.cye-enabled.cye-lm select{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style><style id="cyeul">html.cye-enabled.cye-lm ul{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style><style id="cyeChangeByClick">html.cye-enabled.cye-lm .cye-lm-tag,html.cye-enabled.cye-lm.cye-lm-tag{background-color:#cce8cf !important;border-color:rgb(51, 58, 51) !important;background-image:none !important;color:#000000  !important}</style></head><body style="" data-gr-c-s-loaded="true"><h3><center>Yoda's Homepage<center></center></center></h3>

<hr>

<center><img src="yoda.png" style="width:400px;height:500px;"></center>

<hr>



<b>I am Yoda, the Grand Master of the Jedi Order.
<br>

Welcome COMP3331/93313 padawan. May the force be with you.




</b></body><div id="cyeBlackMaskLayer" style="background-color: rgb(19, 19, 19); position: fixed; width: 1980px; height: 1080px; z-index: -2147483648;"></div><div id="cye-workaround-body" style="position: absolute; left: 0px; top: 0px; z-index: -2147483646; background: none 0% 0% / auto repeat scroll padding-box border-box white; height: 659px; width: 1280px;"></div><div id="cye-workaround-body-image" style="position: absolute; left: 0px; top: 0px; z-index: -2147483645; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); height: 659px; width: 1280px;"></div><span class="gr__tooltip"><span class="gr__tooltip-content"></span><i class="gr__tooltip-logo"></i><span class="gr__triangle"></span></span></html>

Tags: imagenoneidindexstylehtmlenabledcontent
1条回答
网友
1楼 · 发布于 2024-04-20 06:40:14

str不能简单地用字节相加。 如果希望在页面中显示img,可以在HTML模板中使用<img src='xxx.jpg'>标签,并使用单个响应来处理img。你知道吗

# coding=utf-8

import socket
import re

HOST = ''
PORT = 8000

# Read index.html, put into HTTP response data
index_content = '''HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'''

file = open('index.html', 'r')
index_content += file.read()
index_content = index_content.encode()
file.close()

# Read picture, put into HTTP response data
file = open('Yoda.png', 'rb')
# pic_content = '''
#     HTTP/1.1 200 ok
#     Content-Type: image/png

#     '''
pic_content = file.read()
file.close()


# Configure socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(100)

# infinite loop
while True:
    # maximum number of requests waiting
    conn, addr = sock.accept()
    request = conn.recv(1024)
    # print(request)
    method = request.decode().split(' ')[0]
    src = request.decode().split(' ')[1]

    print("Connect by: ", addr)
    print("Request is:\n", request)

    # deal wiht GET method
    if method == 'GET':
        print(src)
        if src == '/index.html':
            content = index_content
        elif src == '/yoda.png':
            content = 'HTTP/1.x 200 ok\r\nContent-Type: image/png\r\n\r\n'
            content = content.encode()+pic_content
        elif re.match('^/\?.*$', src):
            entry = src.split('?')[1]      # main content of the request
            content = 'HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'
            content += entry
            content += '<br /><font color="green" size="7">register successs!</p>'
        else:
            continue

    # deal with POST method
    elif method == 'POST':
        form = request.split('\r\n')
        entry = form[-1]      # main content of the request
        content = '''HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'''
        content += entry
        content += '''<br /><font color="green" size="7">register successs!</p>'''

    ######
    # More operations, such as put the form into database
    # ...
    ######

    else:
        continue

    conn.sendall(content)

    # close connection
    conn.close()

实际上,读取静态文件的方法不是友好的。那个代码无法处理 未指定的URL,因为您只读取一次文件。您可以在if条件下读取文件,并使用您在URL中收到的名称来定位要读取的文件。你知道吗

相关问题 更多 >