我无法理解我的练习代码有什么问题

问题描述 投票:0回答:1

此代码来自 Coursera 上著名的 Python for Everyday 课程。

import socket
mysock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(("data.pr4e.org",80))


cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()
mysock.send(cmd)


while True:
    data = mysock.recv(512)  
    if len(data) < 1: 
        break
    print(data.decode(), end='')  # Decode the received bytes and print the data

mysock.close()

这效果很好并返回网址的内容。但是,当我想修改代码以便它请求网址并向程序提供输入时,它永远不会停止运行:

import socket
import re
mysock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 try:
  webad=input("Enter your web address:")
  host_name=(re.findall("^(?:https?:\/\/)?(?:www\.)?([^\/\s]+)", webad))[0]
  mysock.connect((host_name,80))

except Exception as e:
  print(f"There is an error: {e}")

cmd_name=f"GET {webad}"+ " "+ r"HTTP/1.0\r\n\r\n"
cmd = cmd_name.encode()
mysock.send(cmd)

while True:
    data = mysock.recv(512)  
    if len(data) < 1: 
        break
    print(data.decode(), end='') 
mysock.close()

我真的不明白问题是什么。我尝试检查解析的字符串等。它们都很好!然而,该程序会永远继续下去,而没有做它应该做的事情。

python http web-scraping
1个回答
0
投票

您的第一个问题是您发送的

cmd
。如果你打印原始的cmd,它将如下所示:

b'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'

当您修改后的代码发送此信息时

cmd

b'GET http://data.pr4e.org/romeo.txt HTTP/1.0\\r\\n\\r\\n'

发生这种情况是因为您正在使用

r"HTTP/1.0\r\n\r\n"
,它将 URL 这部分的
\
处理为文字字符串,这就是为什么您的代码卡在
data = mysock.recv(512)
行上,它甚至没有完成一次交互while 循环。它只是等待接收数据,但它无法接收数据,因为您连接的
url
不正确。

这是

socket
模块的正常行为,套接字以阻塞模式运行(这是默认设置)。你告诉它读取,它就会等待,直到新数据到达。如果你不希望它永远等待,你必须:

  • 调用

    socket.settimeout()
    几秒钟,然后处理读取过程中发生的超时异常。

  • 使用

    select.select()
    检测套接字何时有待读取的数据,然后调用 socket.recv() 读取 i

© www.soinside.com 2019 - 2024. All rights reserved.