Python 如何使用一个类刮取两个网站

Python 如何使用一个类刮取两个网站,python,web-scraping,pyqt,pyqt4,python-3.5,Python,Web Scraping,Pyqt,Pyqt4,Python 3.5,我试图用PyQt呈现用java编写的网站。第一个站点的渲染没有问题,我可以从中获取所需的信息,但是当我想使用同一个类渲染另一个站点并检索新数据时,它告诉我在渲染类中定义的框架没有定义(这是为第一个站点定义的,它在检索我所需的数据时工作得非常好). 那么,为什么会发生这种情况?我是否缺少Python中的一些基本功能?我的理解是,当第一个站点被渲染时,对象将被垃圾收集,第二个站点可以被渲染。以下是参考代码: import sys from PyQt4.QtGui import * from

我试图用PyQt呈现用java编写的网站。第一个站点的渲染没有问题,我可以从中获取所需的信息,但是当我想使用同一个类渲染另一个站点并检索新数据时,它告诉我在渲染类中定义的框架没有定义(这是为第一个站点定义的,它在检索我所需的数据时工作得非常好). 那么,为什么会发生这种情况?我是否缺少Python中的一些基本功能?我的理解是,当第一个站点被渲染时,对象将被垃圾收集,第二个站点可以被渲染。以下是参考代码:

import sys  
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *  
from lxml import html 

class Render(QWebPage):  
    def __init__(self, url):  
        self.app = QApplication(sys.argv)  
        QWebPage.__init__(self)  
        self.loadFinished.connect(self._loadFinished)  
        self.mainFrame().load(QUrl(url))  
        self.app.exec_()


    def _loadFinished(self, result):  
        self.frame = self.mainFrame()  
        self.app.quit()

urls = ['http://pycoders.com/archive/', 'http://us4.campaign-archive2.com/home/?u=9735795484d2e4c204da82a29&id=64134e0a27']

for url in urls:
    r = Render(url)
    result = r.frame.toHtml()
    #This step is important.Converting QString to Ascii for lxml to process
    #QString should be converted to string before processed by lxml
    formatted_result = str(result)
    #Next build lxml tree from formatted_result
    tree = html.fromstring(formatted_result)
    #Now using correct Xpath we are fetching URL of archives
    archive_links = tree.xpath('//div[@class="campaign"]/a/@href')[1:5]
    print (archive_links)
我收到的错误消息是:

  File "javaweb2.py", line 24, in <module>
    result = r.frame.toHtml()
AttributeError: 'Render' object has no attribute 'frame'
文件“javaweb2.py”,第24行,在
result=r.frame.toHtml()
AttributeError:“Render”对象没有属性“frame”

任何帮助都将不胜感激

这是因为
self.frame
仅在调用
self.\u loadFinished()
时定义,这仅在
QWebPage
实例发出信号时发生。因此,除非我在您发布的代码中看到一些可疑的做法,否则以下内容将解决问题(与****无关):

所以“pass”可以工作,但会消耗100%的cpu,因为循环每秒执行一百万次。使用计时器仅每1/10秒检查一次,cpu消耗非常低


当然,最好的解决方案是将取决于可用帧的逻辑(即当前在
r=Render(URL)
下面的URL循环中的代码)放入一个函数中,该函数将在发出
loadFinished
信号时被调用。由于无法控制信号的顺序,最好的选择是将该代码移动到
\u loadfinished()
方法中

我将建议的代码放入_loadfinished()方法中,并从主函数内部调用该类。它可以很好地使用一个url,但只要我想呈现两个网站,一个接一个,它就会挂在第一个网站的第一个呈现对象中。似乎我必须以某种方式跳出render类(更改事件循环的范围)才能继续第二个网站。有办法做到这一点吗?使用exit()只会退出程序。也许python应用程序必须关闭并重新打开才能呈现下一个页面,这是不可能的,因为应用程序在终端中重新打开了?您可以在修复代码的同时发布一个单独的问题吗。谢谢。这是另外一个问题:
class Render(QWebPage):  
    def __init__(self, url):  
        self.app = QApplication(sys.argv)  
        self.frame = None  # *****
        QWebPage.__init__(self)  
        self.loadFinished.connect(self._loadFinished)  
        self.mainFrame().load(QUrl(url))  
        self.app.exec_()

    def _loadFinished(self, result):  
        self.frame = self.mainFrame()  
        self.app.quit()

urls = ['http://pycoders.com/archive/', 'http://us4.campaign-archive2.com/home/?u=9735795484d2e4c204da82a29&id=64134e0a27']

for url in urls:
    r = Render(url)
    # wait till frame arrives: 
    while r.frame is None:
        # pass  # option 1: works, but will cause 100% cpu 
        time.sleep(0.1)  # option 2: much better

    result = r.frame.toHtml()
    ...