网页加载数据后抓取网页

2024-06-28 11:00:39 发布

您现在位置:Python中文网/ 问答频道 /正文

试图收集学校项目图书价格波动的数据。我使用Python从一个图书回购聚合器(在本例中是bookscouter)中获取数据,但是我发现由于站点必须加载数据,所以通过urllib2包获取源代码可以获得数据加载前的源代码。加载数据后如何从中提取?在

示例:http://bookscouter.com/prices.php?isbn=9788498383621&searchbutton=Sell


Tags: 数据项目comhttp示例源代码站点价格
2条回答

挑战在于,一旦数据被web浏览器呈现出来,就要读取数据,这需要一些额外的技巧。如果您可以查看站点是否具有预渲染版本*或API。在

This article (linked from the Web archive)对您需要做的事情进行了很好的分解。但可以概括为:

  1. 选择一个好的pythonwebkit呈现器(在文章PyQT中)
  2. 使用窗口小部件获取和呈现页面
  3. 从小部件获取呈现的HTML
  4. 使用lXML或beauthoulsoup之类的库正常解析这个HTML。在

*小题大做-希望得到一个静态网页的预渲染版本的想法激怒了我。

你不能只使用Python。您需要一个JavaScript引擎API,比如PhantomJS

使用Phantom,将非常容易地设置所有页面内容的web抓取,静态和动态JavaScript内容(如Ajax调用结果在您的情况下)。事实上,您可以像(这是一个节点.js+ 幻影.js示例)

/*
     * Register Page Handlers as functions

    {
        onLoadStarted : onLoadStarted,
        onLoadFinished: onLoadFinished,
        onError : onError,
        onResourceRequested : onResourceRequested,
        onResourceReceived : onResourceReceived,
        onNavigationRequested : onNavigationRequested,
        onResourceError : onResourceError
    }

    */
    registerHandlers : function(page, handlers) {
        if(handlers.onLoadStarted) page.set('onLoadStarted',handlers.onLoadStarted)
        if(handlers.onLoadFinished) page.set('onLoadFinished',handlers.onLoadFinished)
        if(handlers.resourceError) page.set('onResourceError', handlers.resourceError)
        if(handlers.onResourceRequested) page.set('onResourceRequested',handlers.onResourceRequested)
        if(handlers.onResourceReceived) page.set('onResourceReceived',handlers.onResourceReceived)
        if(handlers.onNavigationRequested) page.set('onNavigationRequested',handlers.onNavigationRequested)
        if(handlers.onError) page.set('onError',handlers.onError)

    }

此时,您可以完全控制正在进行的操作,以及在页面中何时需要下载,如:

^{pr2}$

如您所见,您可以定义页面处理程序并控制流以及加载到该页面上的资源。因此,在获取整个页面源之前,您可以确保所有数据都已准备好并设置好,例如:

var Parser = {
  parse : function(page) {

    var onSuccess = function (page) { // page loaded
        var pageContents=page.evaluate(function() {
            return document.body.innerText;
        });
      }
    var onError = function (page,elapsed) { // error
    }
    page.evaluate(function(func) {
            return func(document);
        }, function(dom) {
            return true;
        });

  }
} // Parser

在这里您可以看到onSuccess回调中加载的整个页面内容:

var pageContents=page.evaluate(function() {
                return document.body.innerText;
            });

该页面直接来自Phantomjs,如下代码片段所示:

phantom.create(function (ph) {
            ph.createPage(function (page) {
                Parser.parse(page)
            })
        },options)

当然,这是给你和你的想法,你可以做什么节点.js+幻影,当结合在一起的时候是超级强大的。在

可以在Python环境中运行phantomjs,将其称为

try:
            output = ''
            for result in runProcess([self.runProcess,
            self.runScript,
            self.jobId,
            self.protocol,
            self.hostname,
            self.queryString]):
                output += '' + result
                print output
        except Exception as e:
            print e
            print(traceback.format_exc())

使用子进程Popen执行二进制文件的位置:

def runProcess(exe):
    p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while(True):
      retcode = p.poll() #returns None while subprocess is running
      line = p.stdout.readline()
      yield line
      if(retcode is not None):
        break

当然,要运行的过程是节点.js在这种情况下

self.runProcess='node'

用你需要的参数作为参数。在

相关问题 更多 >