You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多线程URL爬取任务卡在最后一个任务的问题求助

可能的原因及排查方向

1. 字符串格式化的低级错误

你的send_request和logic_a调用中错误使用了f-string:

res = send_request(f"input_tuple[1]")
some_data = logic_a(f"input_tuple[1]")

这里的写法会把input_tuple[1]当作字面量字符串传递给接口,而不是取元组的第二个元素(实际URL)。正确写法应该是直接传入变量:

res = send_request(input_tuple[1])
some_data = logic_a(input_tuple[1])

这个错误会导致大部分请求调用无效地址,直接返回None,部分任务的异常行为可能间接引发后续阻塞。

2. 日志记录代码的规范问题

logging.info("error in main: ", e)不符合logging模块的使用规范,应该用格式化字符串传递异常信息:

logging.info("error in main: %s", e)
# 或者使用f-string
logging.info(f"error in main: {e}")

原写法中,e会被当作额外参数处理,如果e的类型无法被正确格式化,会在异常处理块中抛出新的未捕获异常——而executor.map的迭代器会在遍历到对应任务时才暴露这个异常,导致遍历过程卡住。

3. 数据库操作的阻塞或死锁

logic_a中的数据库写入操作可能存在以下问题:

  • 未提交事务:如果开启了事务但忘记提交,数据库连接会被持续占用,线程看似执行完日志,实际卡在事务等待环节。
  • 连接池耗尽:未正确复用或关闭数据库连接,多次迭代后连接池被占满,后续任务的DB操作阻塞。
  • 数据库死锁:多线程同时写入时出现行锁/表锁冲突,导致线程阻塞无法完成。
    即使日志在logic_a之后输出,也不代表数据库操作已完全完成(部分驱动的写入是异步提交的)。

4. 隐性的任务阻塞

main函数中可能存在未处理的阻塞逻辑:

  • send_request未设置超时,某个URL的请求一直挂起,线程看似执行完日志但实际卡在IO等待。
  • logic_a的HTML解析或DB操作存在未被捕获的死循环、阻塞调用。
    with ThreadPoolExecutor块退出时会等待所有任务完成,只要有一个任务未真正结束,整个块就会一直阻塞,后续的for result in results自然无法执行。

5. 迭代器遍历的异常未被捕获

executor.map返回的是迭代器,遍历它时才会逐个返回结果或抛出异常。如果某组任务中存在未被main捕获的异常,遍历到该位置时程序会终止或卡住。可以给遍历逻辑加一层异常捕获:

try:
    for result in results:
        print(result)
except Exception as e:
    logging.error(f"Error when iterating results: {e}")

内容的提问来源于stack exchange,提问作者tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:43:34