Javascript 用Python执行网页脚本

Javascript 用Python执行网页脚本,javascript,python,windows,web-scraping,pyqt4,Javascript,Python,Windows,Web Scraping,Pyqt4,我正试图抓取一个充满javascript的页面。网址是: 我使用了以下代码来获取数据。显然,这段代码应该处理javascript并返回一个完整的html文件,但事实并非如此。可能存在时间问题,如果是这样的话,我不太清楚您在哪里延迟程序以允许完整的html import sys from PyQt4.QtGui import * from PyQt4.QtCore import * from PyQt4.QtWebKit import * class Render(QWebPage):

我正试图抓取一个充满javascript的页面。网址是:

我使用了以下代码来获取数据。显然,这段代码应该处理javascript并返回一个完整的html文件,但事实并非如此。可能存在时间问题,如果是这样的话,我不太清楚您在哪里延迟程序以允许完整的html

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

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()

def getHtml(str_url):
    r_html = Render(str_url)
    html = r_html.frame.toHtml()
    return html

str_url = 'http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840'
str_html = getHtml(str_url)
print(str_html)
这将为我提供html,如果您从web浏览器请求页面源,您将获得html。当然,页面上还有更多内容,因为所有的表都充满了javascript函数。使用Firebug,我要查找的表的id是“SharesInExtable。我真正想抓取的项目是每个公司名称下的链接-但是使用beautifulsoup访问整个表进行解析会更好。从这个表中,应该可以找到“Carlsberg”一词(作为查看AJAX是否已完全加载的潜在测试)。然后我试图找出解析DOM的方法,我尝试了以下方法:

import sys
from PyQt4 import QtGui, QtCore, QtWebKit

class Sp():
    def printit(self):        
        data = self.webView.page().mainFrame().findFirstElement('id="sharesInIndexTable"')
    print(data)       

def main(self):
    self.webView = QtWebKit.QWebView()
    self.webView.load(QtCore.QUrl("http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840"))
    QtCore.QObject.connect(self.webView,QtCore.SIGNAL("loadFinished(bool)"),self.printit)

    app = QtGui.QApplication(sys.argv)
    s = Sp()
    s.main()
    sys.exit(app.exec_())
我从中得到的是0x03294830处的PyQt4.QtWebkit.QWebElement对象(您的结果可能会有所不同)。我尝试将此地址转换为可读格式的任何操作都失败了。此代码似乎也运行了两次。 然后我尝试了这个(有点适合我的需要):

我添加了print()语句,以确定程序是否完全执行了命令。这根本不会产生任何结果(除了print语句)

查看源页面,我可以找到填充表的脚本,它是:

var sharesInIndex = { 
load: function () {
var index = webCore.getInstrument();
var nLabel = 'nm';
var hiddenAttributes = ",lists,tp,hlp,isin,note,";
var xslt = "inst_table.xsl";
var options =  ",noflag,sectoridicon,";
var xpath = "//index//instruments";
// Check if swedish r�nteindex or Icelandic r�nteindex.
if ( index.indexOf('OMFSE') >= 0 || webCore.getInstrument().indexOf('IS00000') >= 0 ) {
    hiddenAttributes += ",to,sectid,";
    nLabel = 'fnm';
}

// Check if weights index present (typeof)
var shbindex = ",SE0002834820,SE0002834838,SE0002834846,SE0002977397,";
if ( shbindex.indexOf(index) >= 0 ) {
    xslt = "inst_table_windex.xsl";
    options += "windex,";
    xpath = "//index";
}

var query = webCore.createQuery(
    Utils.Constants.marketAction.getIndexInstrument, {
    inst__a: "0,1,2,5,37,4,20,21,23,24,33,34,97,129,98,10", /* 87,*/
    Instrument: index,
    XPath: xpath,
    ext_xslt: xslt,
    ext_xslt_lang: currentLanguage,
    ext_xslt_tableId: "sharesInIndexTable",
    ext_xslt_hiddenattrs: hiddenAttributes,
    ext_xslt_notlabel: nLabel,
    ext_xslt_options: options
  });

  $("#sharesInIndexOutput").empty().loading("/static/nordic/css/img/loading.gif");
  $("#sharesInIndexOutput").load( webCore.getProxyURL('prod'), {xmlquery: query},
    function( responseText, textStatus, XMLHttpRequest) {
      $("#sharesInIndexTable").tablesorter({
        widgets: ['zebra'], 
        textExtraction: 'complex', 
        numberFormat: Utils.Constants.numberFormat[currentLanguage]
        });
      $("#sharesInIndexTable a").each( function() {
        $(this).attr("href",webCore.getURL( Utils.Constants.pages.micrositeShare, $(this).attr('name') ));
      });
    });
  }
};

$(document).ready( sharesInIndex.load );
我知道有一个“execute_script”命令,但我不知道如何实现它,也没有找到任何适合的例子——我不介意结果是Json、HTML还是纯文本。我相信答案就在这里:(1)加载页面,(2)运行页面脚本,(3)获取结果,(4)解析/打印/保存结果

如果有一个无头解决方案的话,我会选择无头解决方案,即使windows上的Phantomjs也不会完全无头,因为它会弹出一个cmd窗口(我知道你可以通过Linux上的虚拟显示来解决这个问题,但这不是环境)。另外,只要告诉我:哦,你必须轮询它,看看是否加载了数据,然后你检索它,这不是很有帮助:你能告诉我(即使是伪代码)轮询是如何完成的,更重要的是,轮询在程序中的大致位置发生吗(这就是我发布完全可执行代码的原因——如果其他人有同样的问题,他们应该有一个完整且易于理解的答案)

我的最新尝试(1-插入延迟以允许AJAX加载)

(2-轮询源页面中的已知项)-使用firebug inspector找到的项-可能findFirst参数的语法错误

import sys  
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *
import time

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

  def _loadFinished(self, result):
    counter = 0
    while(self.mainFrame().documentElement().findFirst("id=sharesInIndexTable")):
      counter+=1
      print(counter)
      time.sleep(1)    
    self.frame = self.currentFrame()  
    self.app.quit()  

url = 'http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840'  
r = Render(url)  
html = r.frame.toHtml()
print(html)
最后一个有一个计数器来显示是否发生了什么事情。它永远计数,必须用ctrl-c停止

(3-使用WebElement的另一个变体)

导入系统 从PyQt4.QtGui导入* 从PyQt4.QtCore导入* 从PyQt4.QtWebKit导入* 导入时间 类呈现(QWeb页面): 定义初始化(self,url): self.app=QApplication(sys.argv) QWebPage.\uuuuu init\uuuuuuuuuu(自我) self.mainFrame().load(QUrl(url)) self.loadFinished.connect(self.\u loadFinished) self.app.exec() def_加载完成(自身、结果): table=self.mainFrame().documentElement().findFirst(“id=SharesInExtable”) 打印(表格)#打印: 打印(“属性:”) 打印(table.attributeNames())#打印:[]即无 打印(“类:”) 打印(table.classes())#打印:[]即无 打印(“InnerXML:+table.toInnerXml())#不打印任何内容 打印(“OuterXML:+table.toOuterXml())#不打印任何内容 打印(“完成”) self.frame=self.currentFrame() self.app.quit() url='1〕http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840' r=呈现(url) html=r.frame.toHtml()
这一次也没有成功。我把打印出来的东西输入了代码。那里显然有一个物体,但我看不到里面有什么。

我知道已经很久了,但这个答案是为以后遇到类似情况的访客准备的

我遇到了一个类似的问题,我尝试了各种方法,比如等待来自QWebPage和QWebFrame的loadFinished信号,等待来自QWebFrame.IntialYoutCompleted()的信号等等

最终对我起作用的是:

我只是在普通浏览器中呈现页面。检查了由于javascript而无法在PyQt中呈现的元素,获取了该元素的id(如果它是一个div,反过来又包含多个元素、表等,则获取div id)。现在在yourPage.loadFinished函数中的python代码中调用yourFrame.evaluateJavaScript(“getElementById(element\u id\u检索到的\u更早'))


这将等待id被检索,而id将等待嵌入式脚本被执行。

我尝试使用和elementID='instrument factsheet'实现您的解决方案,但我一定没有做到这一点。请您发布一些方法的代码片段。谢谢。
import sys  
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *
import time

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

  def _loadFinished(self, result):
    time.sleep(5)
    self.frame = self.currentFrame()  
    self.app.quit()  

url = 'http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840'  
r = Render(url)  
html = r.frame.toHtml()
print(html)
import sys  
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *
import time

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

  def _loadFinished(self, result):
    counter = 0
    while(self.mainFrame().documentElement().findFirst("id=sharesInIndexTable")):
      counter+=1
      print(counter)
      time.sleep(1)    
    self.frame = self.currentFrame()  
    self.app.quit()  

url = 'http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840'  
r = Render(url)  
html = r.frame.toHtml()
print(html)
import sys  
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *
import time

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

  def _loadFinished(self, result):
    table = self.mainFrame().documentElement().findFirst("id=sharesInIndexTable")
    print(table)    #prints: <PyQt4.QtWebKit.QWebElement object at 0x0319FB0>
    print("Attributes:")
    print(table.attributeNames())    #prints: [] i.e. None 
    print("Classes: ")
    print(table.classes())      #prints: [] i.e. None
    print("InnerXML: " + table.toInnerXml())   #prints nothing
    print("OuterXML: " + table.toOuterXml())   #prints nothing
    print("Done")
    self.frame = self.currentFrame()  
    self.app.quit()  

url = 'http://www.nasdaqomxnordic.com/index/index_info?Instrument=DK0016268840'  
r = Render(url)  
html = r.frame.toHtml()