【问题标题】:Try to build WebServer and read html FILE, with TypeError: must be str, not bytes尝试构建 WebServer 并读取 html 文件,TypeError: must be str, not bytes
【发布时间】:2018-03-24 14:02:07
【问题描述】:

我尝试通过python3构建一个简单的WebServer。并在互联网上找到许多示例代码。在所有示例中,它们都使用类似

的代码
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()

这是 index.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>

【问题讨论】:

  • 你是怎么得到index_content的?看起来那不是str。尝试通过type(index_content)获取它的类型

标签: python python-3.x http webserver


【解决方案1】:

str 不能简单地与字节相加。 如果你想在页面中显示img,你可以在你的HTML模板中使用&lt;img src='xxx.jpg'&gt;标签,并使用单个响应来处理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条件下的文件,并使用您在urls中收到的名称来定位文件进行读取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-04
    • 2014-03-08
    • 1970-01-01
    • 2019-05-10
    • 2020-05-29
    • 2018-12-23
    相关资源
    最近更新 更多