首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过子类化QNetworkAccessManager来使用createRequest伪造请求?

如何通过子类化QNetworkAccessManager来使用createRequest伪造请求?
EN

Stack Overflow用户
提问于 2013-04-13 22:43:31
回答 1查看 840关注 0票数 0

我想从网站上下载动态生成的图像。该网站有javascript代码和点击按钮,以转到上一张图片和下一张图片。我检查了chrome中的http请求和响应。除了图像名称之外,请求几乎是相同的(它的数字递增形式类似:000001.jpg,000002.jpg)。现在,我可以访问第一个图像,并通过使用自定义QNetworkAccessManager将QWebView子类化来将其保存到磁盘。我重载了createRequest函数:

代码语言:javascript
运行
复制
import sys,urllib,time,os
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtNetwork import *
from PIL import Image

class NetworkAccessManager(QNetworkAccessManager):
    def __init__(self,old_manager):
    QNetworkAccessManager.__init__(self)
    self.old_manager = old_manager
    self.setCache(old_manager.cache())
    self.setCookieJar(old_manager.cookieJar())
    self.setProxy(old_manager.proxy())
    self.setProxyFactory(old_manager.proxyFactory())
    self.imreply=None
    self.reqstr=None
    self.otherreply=None
    self.current_req=None
    self.cnt=0
    self.jpgName="test.jpg"
    self.first=True
    self.ba=QByteArray()
    self.ba.clear()

    def createRequest(self, operation, request, data):
        req = request.url().toString()
        if req.contains(QString("zoom=")) and req.contains(QString("ss2jpg")) and not req.contains(QString("pi=2")):
            strreq=str(req)
            l=strreq.find("jid=")
            r=strreq.find(".jpg&a")
            self.jpgName=strreq[l+5:r+4]
            self.jpgcnt=int(strreq[l+5:r])
            print self.jpgName,self.jpgcnt
            self.imreply=QNetworkAccessManager.createRequest(self,operation, request, data)
            self.connect(self.imreply,SIGNAL("readyRead()"),self.saveImage)
            return self.imreply
        elif req.contains(QString("uf=ssr")):
            strreq=str(req)
            self.reqstr=strreq
            self.current_req=request
            r=strreq.find("?")
            self.jpgcnt=int(strreq[r-6:r])
            self.otherreply=QNetworkAccessManager.createRequest(self,operation, request, data)
            return self.otherreply
        else:
            return QNetworkAccessManager.createRequest(self,operation, request, data)

    def saveImage(self):
        if self.imreply.header(QNetworkRequest.ContentTypeHeader).toString().contains(QString("image/jpeg")) or self.imreply.header(QNetworkRequest.ContentTypeHeader).toString().contains(QString("image/png")):
            contentLen,flag = QString(self.imreply.rawHeader("Content-Length")).toInt()
            self.ba=self.ba.append(self.imreply.readAll())
            if self.ba.size() == contentLen:
            #self.ba=self.imreply.readAll()
            im=QImage.fromData(self.ba)
            im.save(self.jpgName)
            im=Image.open(self.jpgName)
            print "saving image",contentLen,self.jpgName
            im.save(self.jpgName)
            self.ba.clear()
            self.emit(SIGNAL("nextPage()"))

class dxWebView(QWebView):
    def __init__(self):
        QWebView.__init__(self)

    def clickNext(self):
        manager=self.page().networkAccessManager()
        if manager.cnt<50:
            nextreq=manager.current_req
            nexturl=manager.reqstr.replace(str(manager.jpgcnt),str(manager.jpgcnt+1))
            print "next url",nexturl
            nextreq.setUrl(QUrl(nexturl))
            manager.get(QNetworkRequest(nextreq))
            manager.cnt=manager.cnt+1

def main():
    app=QApplication(sys.argv)
    QWebSettings.globalSettings().setAttribute(QWebSettings.PluginsEnabled, True);
    view=dxWebView()
    old_manager=view.page().networkAccessManager()
    new_manager=NetworkAccessManager(old_manager)
    view.page().setNetworkAccessManager(new_manager)
    QObject.connect(new_manager,SIGNAL("nextPage()"),view.clickNext)
    url="http://www.yishuleia.cn/DrsPath.do?kid=686A67696A6F6A673134343438303337&username=gdnz2&spagenum=201&pages=50&fid=14813857&a=3fc3e380601ced0f08749c964294120e&btime=2013-04-03&etime=2013-04-23&template=bookdsr1&firstdrs=http%3A%2F%2Fbook.duxiu.com%2FbookDetail.jsp%3FdxNumber%3D000008299393%26d%3D592DC22226A893A958A6578E7D039A43"
    view.load(QUrl(url))
    view.show()
    sys.exit(app.exec_())

if __name__=='__main__':
    main()

当第一个图像被保存时,clickNext被触发并且qnetworkaccessmanager发送下一个request.But我发现manager.get(nextreq)没有work.The http分析器没有筛选任何http请求和响应。我是不是在clickNext函数中错了?该怎么做呢?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-04 19:04:27

因此,QNetworkAccessManager是QWebPage对象的一部分,只要有来自呈现的createRequest(及其包含的任何javascript )的资源请求,就会调用HTML ()方法。据我所知,clickNext()函数并不能以您所需的方式访问网页的实际DOM。

如果你的目标是构建一个可以下载所有这些图片的应用程序,你可以在网站上运行一些简单的javascript,它会自动点击到“下一张”图片。然后,正如您所做的那样,您将在重载的createRequest()函数中观察加载图像的请求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15988988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档