Как узнать точный URL для загрузки изображений с помощью QNetworkAccessManager - PullRequest
1 голос
/ 01 мая 2019

Я использую QNetworkAccessManager для загрузки изображений.

В первый раз я должен указать URL изображений.

Но по-другому.

Например, я получаю изображение с Wikipedia Top Page Японский .

Есть несколько загружаемых изображений.

Если я скопирую тексты и изображения, а затем вставлю их в свой редактор, HTML-текст содержит URL.

Даже если я передаю его в QNetworkRequest, я не могу загрузить изображение.

После того, как я копаюсь в URL и получаю файл изображения в Wikipedia Commons , Если я передам URL в QNetworkRequest, я могу загрузить изображения.

Я уже понял, что URL должен быть точным, но я не знаю, как их различать.

Знаете ли вы, как программно загружать изображения каждый раз, не ошибаясь?

Можно ли заранее узнать точный URL-адрес?

У меня нет особых знаний о сети.

Я часто принимаю UnknownContentError

Как использовать для примера кода

Ctrl + C копирование текстов и изображений (укажите изображение) Ctrl + V вставить html и загрузить изображение

Q Загрузка изображения напрямую. Я могу скачать только этим.

Пример кода

from PySide import QtCore, QtGui, QtNetwork
from bs4 import BeautifulSoup
import sys, os, re
class Widget(QtGui.QTextEdit):
    def __init__(self, parent=None):
        super(Widget, self).__init__()   

    def keyPressEvent(self, event):
        if event.modifiers() == QtCore.Qt.KeyboardModifier.ControlModifier and event.key() == QtCore.Qt.Key_C:
            tc = self.textCursor()                       
            mimedata = self.createMimeDataFromSelection()
            clipboard = QtGui.QApplication.clipboard()
            clipboard.setMimeData(mimedata)
            start = tc.selectionStart()
            end = tc.selectionEnd()                   
            char = tc.charFormat()
            char.clearBackground()
            tc.setCharFormat(char)             
            return 
        elif event.modifiers() == QtCore.Qt.KeyboardModifier.ControlModifier and event.key() == QtCore.Qt.Key_V:
            clipboard = QtGui.QApplication.clipboard()

            html = clipboard.mimeData().html()                      
            pous = BeautifulSoup(html,"lxml")
            image_items  = pous.find_all('a', href=re.compile('(\.jpg|\.png|\.svg|\.gif)$'))
            image_urls = [item.get('href') for item in image_items]      
            for i, url in enumerate(image_urls):                    
                #indirect url  https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Oguri_Cap_in_Yushun_Stallion_station.jpg
                print(url)
                request = QtNetwork.QNetworkRequest(QtCore.QUrl(url))       
                self.nam = QtNetwork.QNetworkAccessManager() 
                self.nam.finished[QtNetwork.QNetworkReply].connect(self.doReply)
                self.nam.get(request)
        if event.key() == QtCore.Qt.Key_Q:
            self.doRequest()
    def doRequest(self):        
        # direct url & exact url
        url = "https://upload.wikimedia.org/wikipedia/commons/c/c3/Oguri_Cap_in_Yushun_Stallion_station.jpg"
        req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))    
        self.nam = QtNetwork.QNetworkAccessManager()     
        self.nam.finished[QtNetwork.QNetworkReply].connect(self.doReply)       
        self.nam.get(req)    
    def doReply(self, reply):
        er = reply.error()
        if er == QtNetwork.QNetworkReply.NoError:    
            data = reply.readAll()            
            self.saveImage(data)                    
        else:
            print( "Error occured: ", er)
            print(  reply.errorString())
    def saveImage(self, data):
        try:           
            im = QtGui.QImageWriter()            
            im.setFileName(os.path.join(os.getcwd(),"wiki_topimage.png"))           
            imd = QtGui.QImage()
            imd_bool = imd.loadFromData(data.data())
            im.write(imd)
        except Exception as e:
            print(e)

def main():
    QtCore.QCoreApplication.addLibraryPath(os.path.join(os.getcwd(),"plugins"))  
    try:
        QtGui.QApplication([])

    except Exception as e:
        print("error", e)
    w = Widget()
    w.show()
    sys.exit(QtGui.QApplication.exec_())
if __name__ == "__main__":
    main()

1 Ответ

1 голос
/ 02 мая 2019

У вас есть следующие ошибки:

  • URL, который вы должны использовать, находится в атрибуте src дочернего тега img.
  • Вам нужно только создать QNetworkAccessManager, так как в противном случаеНовый QNetworkAccessManager исключит предыдущий.
  • Вы должны использовать QUrl :: fromUserInput () , поскольку он обрабатывает URL-адреса, пробуя несколько конфигураций, например, в этом случае он может преобразовать URL-адрес:
https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Oguri_Cap_in_Yushun_Stallion_station.jpg

до

https://ja.wikipedia.org/wiki/ファイル:Oguri_Cap_in_Yushun_Stallion_station.jpg
import os
import sys
import re
from PySide import QtCore, QtGui, QtNetwork
from bs4 import BeautifulSoup


class Widget(QtGui.QTextEdit):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.nam = QtNetwork.QNetworkAccessManager(self)
        self.nam.finished[QtNetwork.QNetworkReply].connect(self.doReply)

    def keyPressEvent(self, event):
        if event.matches(QtGui.QKeySequence.Copy):
            tc = self.textCursor()
            mimedata = self.createMimeDataFromSelection()
            clipboard = QtGui.QApplication.clipboard()
            clipboard.setMimeData(mimedata)
            start = tc.selectionStart()
            end = tc.selectionEnd()
            char = tc.charFormat()
            char.clearBackground()
            tc.setCharFormat(char)
            return
        elif event.matches(QtGui.QKeySequence.Paste):
            clipboard = QtGui.QApplication.clipboard()

            html = clipboard.mimeData().html()
            pous = BeautifulSoup(html, "lxml")
            image_items = pous.find_all(
                "a", href=re.compile(r"(\.jpg|\.png|\.svg|\.gif)$")
            )
            for i, item in enumerate(image_items):
                url = item.find("img", recursive=False).get("src")
                print(i, url)
                request = QtNetwork.QNetworkRequest(
                    QtCore.QUrl.fromUserInput(url)
                )
                self.nam.get(request)

    @QtCore.Slot(QtNetwork.QNetworkReply)
    def doReply(self, reply):
        er = reply.error()
        if er == QtNetwork.QNetworkReply.NoError:
            print("ok", reply.url())
            name = reply.url().path().split("/")[-1]
            filename = os.path.join(os.getcwd(), name)
            file = QtCore.QFile(filename)
            if file.open(QtCore.QIODevice.WriteOnly):
                file.write(reply.readAll())
        else:
            print("Error occured: ", er, reply.url())
        reply.deleteLater()


def main():
    QtCore.QCoreApplication.addLibraryPath(os.path.join(os.getcwd(), "plugins"))
    app = QtGui.QApplication.instance()
    if app is None:
        app = QtGui.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(QtGui.QApplication.exec_())


if __name__ == "__main__":
    main()
...