【问题标题】:Why am I just taking the picture url from the last url?为什么我只是从最后一个 url 中获取图片 url?
【发布时间】:2021-10-22 02:36:15
【问题描述】:

我写了一个从网络漫画中提取链接图片的程序,但是,当我运行它时,它只是从最后一个链接章节中提取图像链接,而不是从所有章节中提取所有图像链接。我的程序有什么问题? 我尝试了几种方法,但都没有用。

from PyQt5 import QtNetwork, QtCore
from requests_html import HTML
from functools import cached_property
from PyQt5.QtCore import QCoreApplication, QUrl

url1 = "https://saytruyen.net/truyen-su-tro-lai-cua-phap-su-hac-am-sau-66666-nam.html"

class Manager:
    def __init__(self):
        self.manager.finished.connect(self.handle_response)

    @cached_property
    def manager(self):
        return QtNetwork.QNetworkAccessManager()

    def start(self):
        self.start_request(QtCore.QUrl(url1))

    def start_request(self, url):
        request = QtNetwork.QNetworkRequest(url)
        self.manager.get(request)

    def handle_response(self, reply):
        err = reply.error()
        if err == QtNetwork.QNetworkReply.NoError:
            self.process(str(reply.readAll(), 'utf-8'))
        else:
            print("Error occured: ", err)
            print(reply.errorString())

    def process(self, data):
        html = HTML(html=data)
        rs = html.find("#list-chapter a", first=False)
        for i in reversed(rs):
            url2 = "https://saytruyen.net/" + i.attrs["href"]
            #print(url2)
            #self.start_request(QtCore.QUrl(url2))
            req = QtNetwork.QNetworkRequest(QUrl(url2))

            self.nam = QtNetwork.QNetworkAccessManager()
            self.nam.finished.connect(self.handleResponse)
            self.nam.get(req)

    def handleResponse(self, reply):

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            bytes_string = reply.readAll()
            html2 = HTML(html = str(bytes_string, 'utf-8'))
            rs_c = html2.find("#lst_content img")
            for x in rs_c:
                img ="https://saytruyen.net/" + x.attrs['src']
                print(img)

        else:
            print("Error occured: ", er)
            print(reply.errorString())
        
        QCoreApplication.quit()

【问题讨论】:

  • 尝试在__init__中移动self.nam的前两行。
  • 这种方式无效
  • 它应该:问题是你在 for 循环中不断地重新创建一个新的 QNetworkAccessManager,所以结果是前一个被垃圾收集(删除)并且只有最后一个创建的能够“生存”并处理请求。应该只存在一个新 url 的管理器,并且只有 self.nam.get(req) 应该存在于 for 循环中。另外,你不应该在handleResponse的末尾明显退出,否则其他请求将永远不会被处理。
  • 哦,谢谢它的工作

标签: python qt pyqt5 qtnetwork


【解决方案1】:

有两个问题:

  1. 用于下载的 QNetworkAccessManager 正在不断重新创建;由于网络请求是异步的,它不会被立即处理,并且会在for循环的下一个循环中与网络管理器一起被销毁,因为它被覆盖了;结果就是前一个请求会被销毁,只有最后一个会“存活”;
  2. 收到第一个回复后立即退出应用程序,阻止处理所有其他请求;

解决方案是在__init__ 中为下载过程创建一个单个管理器,并在收到所有请求后立即退出。

class Manager:
    def __init__(self):
        self.manager.finished.connect(self.handle_response)
        self.nam = QtNetwork.QNetworkAccessManager()
        self.nam.finished.connect(self.handleResponse)
        self.urls = set()

    # ...

    def process(self, data):
        html = HTML(html=data)
        rs = html.find("#list-chapter a", first=False)
        for i in reversed(rs):
            url2 = QUrl("https://saytruyen.net/" + i.attrs["href"])
            if url2 in self.urls:
                continue
            self.urls.add(url2)
            req = QtNetwork.QNetworkRequest(url2)
            self.nam.get(req)

    def handleResponse(self, reply):
        self.urls.discard(reply.url())
        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:
            bytes_string = reply.readAll()
            html2 = HTML(html = str(bytes_string, 'utf-8'))
            rs_c = html2.find("#lst_content img")
            for x in rs_c:
                img ="https://saytruyen.net/" + x.attrs['src']
                print(img)

        else:
            print("Error occured: ", er)
            print(reply.errorString())

        if not self.urls:
            QCoreApplication.quit()

请注意,拥有一个单个网络管理器并根据排队的请求正确处理响应通常就足够了(而且更好),但对于像这样的简单情况,拥有两个管理器并不代表巨大问题。

【讨论】:

  • 你能用上面的链接给我看完整的代码吗?如果 name == "main"
  • 不,提供的代码就足够了。您不应该只是复制和粘贴解决方案,您应该阅读和研究它们,以便了解它们的作用。
  • 我并不是说我只是复制代码,因为当我运行该行时出现问题:self.urls.add(url2)
  • 那么就告诉你有问题,并澄清什么“问题”是什么。
  • 运行时它给了我一条错误消息,当我将 set() 更改为 input 但离开 set() 并添加 Link 时它没有添加变量,几乎代码不起作用,因为 set () 把整个东西链接出来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 2016-10-04
  • 1970-01-01
相关资源
最近更新 更多