当前位置: 首页 > 知识库问答 >
问题:

python - 求解?爬取电影使用协程出现'任务已销毁,但仍处于挂起状态!'?

乜钱明
2023-06-15

爬取某一部电影 于网上从学习 一步一步操作 没有出现代码错误 但还是出现
'任务已销毁,但仍处于挂起状态!' 在网上看了很多没有看到合适的解决方法 需要把所有的 任务下载完毕 而不是跳过该任务
源代码

import requests
from lxml import etree
import re
from urllib import parse
import asyncio
import aiohttp
import aiofiles


# 发起请求
def get_page_source(url):
    #    获取网址的源代码
    resp = requests.get(url)

    return resp.text


def get_iframe_src(url):
    # 1.拿到页面源代码
    page_source = get_page_source(url)

    # 2.获取源代码中视频的原始地址url 即iframe中的src
    obj = re.compile(r'u60c5"},"url":"(?P<src_url_one>.*?)"')
    result = obj.search(page_source)
    src_url = result.group('src_url_one')
    src_url = src_url.replace('\\', '')
    src_url = 'https://api.imgqiyu.com/bf.php?url=' + src_url

    return src_url


# 获取第一层
def get_fisrt_m3u8_url(src_url):
    page_source = get_page_source(src_url)
    obj = re.compile(r'"source":"(?P<m3u8_url>.*?)"', re.S)
    result = obj.search(page_source)
    m3u8_url = result.group('m3u8_url')
    return m3u8_url


#     获取第二层m3u8地址进行保存
def get_m3u8_file(fisrt_m3u8_url):
    # 下载第一层
    print('下载第一层m3u8')
    fisrt_m3u8 = get_page_source(fisrt_m3u8_url)
    second_m3u8_url = fisrt_m3u8.split()[-1]
    second_m3u8_url = parse.urljoin(fisrt_m3u8_url, second_m3u8_url)
    print('下载成功 并合并第二层地址', second_m3u8_url)
    #     下载第二层
    print('开始下载第二层')
    second_m3u8 = get_page_source(second_m3u8_url)
    with open("second_m3u8.txt", mode='w', encoding='utf-8') as f:
        f.write(second_m3u8)
    print('下载成功并保存')


async def download_one(url):
    for i in range(10):
        try:
            print('开始下载')
            file_name =url.split("/")[-1].strip()
            async with aiohttp.ClientSession() as session:
                async with session.get(url) as resp:
                    content = await resp.content.read()
                    async with aiofiles.open(f'./ts文件_加密/{file_name}',mode='wb')as f:
                        await f.write(content)
            print(url,'下载成功')
        except:
            print(f'下载失败,第{i}次,即将重新下载')



async def download_all_ts():
    tasks = []
    with open('second_m3u8.txt', mode='r', encoding='utf_8') as f:
        for line in f:
            if line.startswith('#'):
                continue
            print(line)
            line = "https://v9.dious.cc" + line
            print(line)

            task = asyncio.create_task(download_one(line))
            tasks.append(task)
    await asyncio.wait(tasks)



def main():
    # url = 'https://www.bj-pfct.com/play/36552-2-1/'
    # # 该网址进行了js加密 目前还不会 将直接用第一个的 M3U8文件网址获取开始
    # # 返回播放器地址
    # print('返回播放器地址')
    # src_url = get_iframe_src(url)
    # print('返回成功', src_url)
    # # 3.请求是src中的页面源代码 获取真正的M3U8文件地址(主要获取该文件) 不用一定要iframe
    # fisrt_m3u8_url = get_fisrt_m3u8_url(src_url)
    # # get_m3u8_file(fisrt_m3u8_url)
    asyncio.run(download_all_ts())


if __name__ == '__main__':
    main()

出现的错误是

Traceback (most recent call last):
  File "D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\base_events.py", line 574, in run_until_complete
    self.run_forever()
  File "D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\base_events.py", line 541, in run_forever
    self._run_once()
  File "D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\base_events.py", line 1750, in _run_once
    event_list = self._selector.select(timeout)
  File "D:\APP\anaconda3.5.3\envs\env_env1\lib\selectors.py", line 323, in select
    r, w, _ = self._select(self._readers, self._writers, [], timeout)
  File "D:\APP\anaconda3.5.3\envs\env_env1\lib\selectors.py", line 314, in _select
    r, w, x = select.select(r, w, w, timeout)
ValueError: too many file descriptors in select()
Task was destroyed but it is pending!
task: <Task pending coro=<download_one() running at D:\pythonProject\pythonscrapy\多线程与多进程\14.异步协程_实战_网吧电影.py:88> wait_for=<Future cancelled> cb=[gather.<locals>._done_callback() at D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\tasks.py:691]>
Task was destroyed but it is pending!
task: <Task pending coro=<download_one() running at D:\pythonProject\pythonscrapy\多线程与多进程\14.异步协程_实战_网吧电影.py:88> wait_for=<Future cancelled> cb=[gather.<locals>._done_callback() at D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\tasks.py:691]>
Task was destroyed but it is pending!
task: <Task cancelling coro=<download_one() running at D:\pythonProject\pythonscrapy\多线程与多进程\14.异步协程_实战_网吧电影.py:88> wait_for=<Future finished result=None> cb=[gather.<locals>._done_callback() at D:\APP\anaconda3.5.3\envs\env_env1\lib\asyncio\tasks.py:691]>
Exception ignored in: <coroutine object download_one at 0x00000129B68FF248>
RuntimeError: coroutine ignored GeneratorExit

共有1个答案

徐佐
2023-06-15

代码写的不错,用了异步操作,不过异步操作有一个缺点,需要注意并发数量,不宜设置过大,否则可能引发这种错误。你的这篇代码的错误就是与并发有关,因为描述太多,导致了你的 select 函数调用出现bug,当然这个问题很好解决,加个限制就行。在你代码的asyncio.run 函数之前增加如下代码即可:


import resource
resource.setrlimit(resource.RLIMIT_NOFILE, (1024, 2048))
 类似资料:
  • 问题内容: 我已经设置了runtime.GOMAXPROCS(2),但是当输出一些数字时,该程序仍然挂起。我可以看到该程序使用了较高的cpu(超过100%),但我不明白为什么for循环goroutine会使我的程序无法正常工作。 在Linux / amd64上,go版本是1.4.2,我的电脑有4个CPU。 这是代码: 问题答案: 永远不需要忙碌的循环,除了消耗CPU时间之外,该循环什么也不做。它不

  • 使用具有2个节点的集群运行Rancher v 2.4.5。我尝试使用Bitnami的Helm Chart安装Wordpress。 一切进展顺利,我可以通过入口访问站点,除了图表创建的L4平衡器由于某种原因仍处于挂起状态。 没有为wordpress服务分配负载平衡器入口: 我已经在Bitnami github上发布了这个问题,但根据回复,这个问题出现在牧场主/RKE方面。 对此有什么想法吗? 附言

  • 嗨,伙计们,我已经写了一个Python爬虫刮...... 我不断地犯错误 “downloader/response_bytes”:9282,“downloader/response_count”:2,“downloader/response_status_count/200”:1,“downloader/response_status_count/301”:1,“finish_reason”:7,

  • 科尔多瓦应用程序在将手机升级到Android 9后停止工作 这是发送请求的代码 当手机连接到wifi时,一切都正常工作,当通过手机切换到数据时,应用程序停止工作。我连接了调试器,所有GET请求都处于状态(挂起)。 我已经在REST客户端应用程序中测试了通过蜂窝连接访问API的能力,它工作正常。 科尔多瓦网络应用程序可以很好地处理这部手机上的蜂窝数据。 Android 9中有什么变化会导致这种行为?

  • 本文向大家介绍详解Python爬取并下载《电影天堂》3千多部电影,包括了详解Python爬取并下载《电影天堂》3千多部电影的使用技巧和注意事项,需要的朋友参考一下 不知不觉,玩爬虫玩了一个多月了。 我愈发觉得,爬虫其实并不是什么特别高深的技术,它的价值不在于你使用了什么特别牛的框架,用了多么了不起的技术,它不需要。它只是以一种自动化搜集数据的小工具,能够获取到想要的数据,就是它最大的价值。 我的爬

  • 问题内容: 我是构建基于ADO.NET的网站的团队的一部分。有时我们有几个开发人员和一个自动化测试工具,它们同时在开发数据库的副本。 我们使用快照隔离级别,据我所知,它使用乐观并发性:它不是锁定,而是希望达到最佳状态,并且如果在受影响的行已在另一方更改期间尝试提交事务,则它会抛出异常交易。 要使用快照隔离级别,我们使用: 并在C#中: 请注意,IsolationLevel Snapshot与Rea