Python多线程下载图片时出现urlopen error[WinError 10048]套接字地址重复使用错误如何解决

urlopen error[WinError 10048] 通常每个套接字地址(协议 /网络地址 /端口)只允许使用一次。

这是怎么回事,各线程抢了端口了吗? 这样搞了一下,也没用

s = requests.Session()
s.keep_alive = False

每个请求,用完后也 r.close() 了, 也没用,不知道啥原因,没见过这个错误啊, 有 v 友知道的吗


Python多线程下载图片时出现urlopen error[WinError 10048]套接字地址重复使用错误如何解决

12 回复

直接在 cmd 里运行 python 脚本,不要在 IDE 里运行


这个问题通常是因为在Windows上,urllibsocket模块在短时间内创建了太多连接,导致端口被占用。解决方法是设置socketSO_REUSEADDR选项,或者使用连接池、限制并发数。

最直接的方案是使用requests库配合Session对象,它会自动管理连接。如果坚持用urllib,可以这样:

import urllib.request
import socket
from urllib.error import URLError

# 创建自定义的OpenerDirector,设置socket选项
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]

# 设置socket选项允许地址重用
class HTTPSHandlerReuse(urllib.request.HTTPSHandler):
    def https_open(self, req):
        return self.do_open(self.get_connection, req)
    
    def get_connection(self, host, timeout=300):
        # 创建socket并设置SO_REUSEADDR
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return sock

# 安装自定义handler
urllib.request.install_opener(opener)

# 然后正常使用urllib.request.urlopen()
try:
    response = urllib.request.urlopen('http://example.com/image.jpg')
    # 处理响应...
except URLError as e:
    print(f"下载失败: {e}")

不过更推荐用requests库,代码更简洁:

import requests
from concurrent.futures import ThreadPoolExecutor, as_completed

def download_image(url, filename):
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        with open(filename, 'wb') as f:
            f.write(response.content)
        return True
    except Exception as e:
        print(f"下载 {url} 失败: {e}")
        return False

# 控制并发线程数,避免创建过多连接
with ThreadPoolExecutor(max_workers=5) as executor:
    futures = []
    for i, url in enumerate(image_urls):
        future = executor.submit(download_image, url, f"image_{i}.jpg")
        futures.append(future)
    
    for future in as_completed(futures):
        result = future.result()

核心是控制并发连接数和使用连接复用。

简单说:限制线程数或用连接池管理。

看图片是不是同一个域名下的,是同一个域名下为啥要关掉 keep-alive ?直接长连接不就好,如果不是一个域名下的就直接短连接吧。

就是在 cmd 中运行的

requests 默认是开着的,就是出现了这个 10048,所以才关了,但也没用

把 python 进程先都关了

只有这一个 python 进程,没有其他的啊,应该是多线程的问题

netstat -ano 看一下,是不是有些进程没有正常关闭,端口被占光了

线程数设置为多少,加了 sleep 了吗?

线程数是根据参数列表自动设置的,目前是 9 个,没加 sleep

同问 我也遇到这问题 了

多进程 没问题 多线程就会出现 这种错误

回到顶部