Python如何使用socket库替代requests获取网页HTML内容
问题排查
- 请求格式错误:Host字段仅可填写纯域名,不可包含
https://前缀、路径内容;HTTP协议要求头部换行必须使用\r\n,不可使用单独\n;HTTPS站点需要对socket套SSL层,且端口需使用443而非HTTP默认的80端口。 - 内容接收不完整:单次
recv(1024)最多仅能读取1024字节内容,仅够承载响应头,后续HTML内容未被接收;HTTP/1.1默认开启长连接,服务器发送完内容后不会主动断开连接,不做特殊处理会导致读取阻塞。
正确实现
在请求头中添加Connection: close字段,要求服务器发送完所有内容后主动断开连接,循环读取所有返回字节即可拿到完整HTML内容,参考代码如下:
import socket import ssl # 目标站点配置,可根据需求修改 HOST = "stackoverflow.blog" PORT = 443 PATH = "/" # 构造标准HTTP请求 request = f"GET {PATH} HTTP/1.1\r\nHost: {HOST}\r\nConnection: close\r\n\r\n" # 创建SSL上下文,兼容性更高 context = ssl.create_default_context() # 自动管理socket资源 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: with context.wrap_socket(sock, server_hostname=HOST) as secure_sock: # 建立连接 secure_sock.connect((HOST, PORT)) # 发送完整请求 secure_sock.sendall(request.encode()) # 循环接收所有返回内容 full_response = b"" while chunk := secure_sock.recv(4096): full_response += chunk # 拆分响应头和HTML正文(不需要可省略该步) response_header, response_html = full_response.split(b"\r\n\r\n", 1) # 输出HTML内容 print(response_html.decode("utf-8"))
如果需要访问之前测试的reddit站点,仅需修改对应HOST、PATH参数即可,逻辑完全通用。
内容的提问来源于stack exchange,提问作者Daniil
相关产品推荐
相关产品推荐

