Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 网页在它之后抓取一页';s加载了它的数据_Python_Web Scraping - Fatal编程技术网

Python 网页在它之后抓取一页';s加载了它的数据

Python 网页在它之后抓取一页';s加载了它的数据,python,web-scraping,Python,Web Scraping,试图为学校项目收集图书价格波动的数据。我正在使用Python从图书回购聚合器(在本例中为BookCouter)中获取数据,但我发现,由于站点必须加载数据,因此通过urllib2包获取源代码会在加载数据之前为我提供源代码。加载数据后如何从中提取 示例:您不能仅使用Python进行此操作。您需要一个JavaScript引擎API,如 使用Phantom,可以非常轻松地设置所有页面内容的web抓取,静态和动态JavaScript内容(如您案例中的Ajax调用结果)。事实上,您可以向页面解析器注册页面事

试图为学校项目收集图书价格波动的数据。我正在使用Python从图书回购聚合器(在本例中为BookCouter)中获取数据,但我发现,由于站点必须加载数据,因此通过urllib2包获取源代码会在加载数据之前为我提供源代码。加载数据后如何从中提取


示例:

您不能仅使用Python进行此操作。您需要一个JavaScript引擎API,如

使用Phantom,可以非常轻松地设置所有页面内容的web抓取,静态和动态JavaScript内容(如您案例中的Ajax调用结果)。事实上,您可以向页面解析器注册页面事件处理程序,如(这是node.js+phantom.js示例)

在这一点上,您可以完全控制正在发生的事情,以及您必须在页面中下载的时间,如:

var onResourceError = function(resourceError) {
                        var errorReason = resourceError.errorString;
                        var errorPageUrl = resourceError.url;
                }
                var onResourceRequested = function (request) {
                    var msg = '  request: ' + JSON.stringify(request, undefined, 4);
                };
                var onResourceReceived = function(response) {
                    var msg = '  id: ' + response.id + ', stage: "' + response.stage + '", response: ' + JSON.stringify(response);
                };
                var onNavigationRequested = function(url, type, willNavigate, main) {
                    var msg = '  destination_url: ' + url;
                    msg += '  type (cause): ' + type;
                    msg += '  will navigate: ' + willNavigate;
                    msg += '  from page\'s main frame: ' + main;
                };
                page.onResourceRequested(
                function(requestData, request) {
                        //request.abort()
                        //request.changeUrl(url)
                        //request.setHeader(key,value)
                        var msg = '  request: ' + JSON.stringify(request, undefined, 4);
                        //console.log( msg )
                    },
                function(requestData) {
                        //console.log(requestData.url)
                })
        PageHelper.registerHandlers(page,
                    {
                        onLoadStarted : onLoadStarted,
                        onLoadFinished: onLoadFinished,
                        onError : null, // onError THIS HANDLER CRASHES PHANTOM-NODE
                        onResourceRequested : null, // MUST BE ON PAGE OBJECT
                        onResourceReceived : onResourceReceived,
                        onNavigationRequested : onNavigationRequested,
                        onResourceError : onResourceError
                    });
正如您所看到的,您可以定义页面处理程序并控制该页面上加载的流和资源。因此,在获取整个页面源代码之前,您可以确保所有数据都已准备就绪并已设置,如:

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)
当然,这是为了让您了解node.js+Phantomjs可以做什么,它们结合在一起时非常强大

您可以在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
当然,在本例中要运行的进程是node.js

self.runProcess='node'

使用所需的参数作为参数。

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

对你需要做的事情有一个很好的分解。但可以总结为:

  • 选择一个好的pythonwebkit呈现程序(在文章PyQT中)
  • 使用窗口小部件获取和呈现页面
  • 从小部件获取呈现的HTML
  • 使用lXML或BeautifulSoup等库正常解析此HTML

  • *小咆哮——我很生气,因为我希望得到一个静态网页的预渲染版本。

    答案总是很美。虽然答案很长,很有趣,但根本不能回答提问者的问题。使用Python有很多方法可以做到这一点,我不建议您使用Python(我是一个有经验的Python开发人员)。Phantomjs(用C++编写)是顶级公司使用的真实Javascript引擎。这是我的2美分()。然后你决定。我会建议使用另一个python web解析器,但不是,我认为这不是最好的答案。但是问题是“我如何用Python做X?”,而X在Python中是可能的,所以不要只回答“不要,用另一种语言就行了。”@legostrmtroopr我不同意。1) 它回答了这样一个事实,即该解决方案在考虑客户端JavaScript VM机器代码执行的情况下呈现整个页面。2) 然后显示要处理哪些事件来实现这一点。3) 它显示了phantomjs如何获取网页、传递到解析器对象页面、注册回调并在正确的时间获取页面内容。@Legostrmtropr是的,但我的答案是。不,忘记python,选择一个更好的解决方案,在我看来,这是一个正确的答案,因为它实现了相同的结果。不管怎样,请随意否决,我也理解你的观点。
    self.runProcess='node'