【问题标题】:Scrape image src URLs using PhantomJS使用 PhantomJS 抓取图像 src URL
【发布时间】:2016-11-30 11:22:21
【问题描述】:

我正在尝试使用 PhantomJS 获取给定网页中所有图像 src url 的列表。我的理解是这应该非常容易,但无论出于何种原因,我似乎都无法让它发挥作用。这是我目前拥有的代码:

var page = require('webpage').create();
page.open('http://www.walmart.com');

page.onLoadFinished = function(){
    var images = page.evaluate(function(){
        return document.getElementsByTagName("img");
    });
    for(thing in a){
        console.log(thing.src);
    }
    phantom.exit();
}

我也试过这个:

var a = page.evaluate(function(){
    returnStuff = new Array;
    for(stuff in document.images){
        returnStuff.push(stuff);
    }
    return returnStuff;
});

还有这个:

var page = require('webpage').create();
page.open('http://www.walmart.com', function(status){
    var images = page.evaluate(function() {
        return document.images;
    });
    for(image in images){
        console.log(image.src);
    }
    phantom.exit();
});

我还尝试在评估函数中迭代图像并以这种方式获取 .src 属性。
他们都没有返回任何有意义的东西。如果我返回 document.images 的长度,页面上有 54 张图像,但尝试遍历它们并没有什么用处。

另外,我查看了以下其他问题,但无法使用他们提供的信息:How to scrape javascript injected image src and alt with phantom.jsHow to download images from a site with phantomjs

再次,我只想要源网址。我不需要实际的文件本身。感谢您的帮助。

更新
我尝试使用

var a = page.evaluate(function(){
    returnStuff = new Array;
    for(stuff in document.images){
        returnStuff.push(stuff.getAttribute('src'));
    }
    return returnStuff;
});

它抛出一个错误,说 stuff.getAttribute('src') 返回未定义。知道为什么会这样吗?

【问题讨论】:

  • console.log([].map.call(document.images, a=>a.src))

标签: javascript web-scraping phantomjs


【解决方案1】:

@MayorMonty 快到了。事实上,你不能返回 HTMLCollection。

作为docs say

注意:评估函数的参数和返回值必须是简单的原始对象。经验法则:如果可以通过 JSON 序列化就可以了。

闭包、函数、DOM 节点等将不起作用!

因此工作脚本是这样的:

var page = require('webpage').create();

page.onLoadFinished = function(){
    
    var urls = page.evaluate(function(){
        var image_urls = new Array;
        var images = document.getElementsByTagName("img");
        for(q = 0; q < images.length; q++){
            image_urls.push(images[q].src);
        }
        return image_urls;
    });    
    
    console.log(urls.length);
    console.log(urls[0]);
    
    phantom.exit();
}

page.open('http://www.walmart.com');

【讨论】:

  • 显示我的答案基于我从控制台获得的结果。 ;)
  • 非常感谢。完美运行
【解决方案2】:

我不确定直接的 JavaScript 方法,但最近我使用 jQuery 来抓取图像和其他数据,因此您可以在注入 jQuery 后以以下样式编写脚本

$('.someclassORselector').each(function(){
     data['src']=$(this).attr('src');
   });

【讨论】:

  • jQuery 没有与 phantomJS 一起打包,这只适用于使用它的网站
  • 其实你可以在任何网站中注入jQuery,你可能还想看看Horseman.js
  • 是的,但是,当您可以使用标准 javascript 方法时,等待 jquery 加载并不总是最好的主意
  • 是的,你是对的,但是编写 jquery 比实际的 JavaScript 更干净,最终它只是偏好问题
【解决方案3】:

document.images 不是一个节点数组,它是一个HTMLCollection,它是由Object 构建的。如果你for..in它,你可以看到这个:

for (a in document.images) {
  console.log(a)
}

打印:

0
1
2
3
length
item
namedItem

现在,有几种方法可以解决这个问题:

  1. ES6 扩展运算符:这会将类数组和可迭代对象转换为数组。像这样使用[...document.images]
  2. 常规的for 循环,就像一个数组。这利用了键被标记为数组的事实:

    for(var i = 0; i < document.images.length; i++) {
      document.images[i].src
    }
    

也许还有更多

使用解决方案 1 允许您在其上使用 Array 函数,例如 mapreduce,但支持较少(idk 如果当前版本的 phantom javascript 支持它)。

【讨论】:

    【解决方案4】:

    我使用以下代码来加载页面上的所有图像,在浏览器上加载的图像会根据视口改变尺寸,因为我想要最大尺寸,所以我使用最大视口来获得实际图片尺寸。

    使用 Phantom JS 获取页面上的所有图像 使用 Phantom JS 下载页面上的所有图片 URL

    即使图像不在代码下方的 img 标记中,您也可以检索 URL


    甚至会检索来自此类脚本的图像

                @media screen and (max-width:642px) {
                    .masthead--M4.masthead--textshadow.masthead--gradient.color-reverse {
                        background-image: url(assets/images/bg_studentcc-750x879-sm.jpg);
                    }
                }
                @media screen and (min-width:643px) {
                    .masthead--M4.masthead--textshadow.masthead--gradient.color-reverse {
                        background-image: url(assets/images/bg_studentcc-1920x490.jpg);
                    }
                }
    

            var page =  require('webpage').create();
            var url = "https://......";
    
            page.settings.clearMemoryCaches = true;
            page.clearMemoryCache();
            page.viewportSize = {width: 1280, height: 1024};
    
            page.open(url, function (status) { 
    
                if(status=='success'){      
                    console.log('The entire page is loaded.............################');
                }
            });
    
            page.onResourceReceived = function(response) {      
                if(response.stage == "start"){
                    var respType = response.contentType;
    
                    if(respType.indexOf("image")==0){           
                        console.log('Content-Type : ' + response.contentType)
                        console.log('Status : ' + response.status)
                        console.log('Image Size in byte : ' + response.bodySize)
                        console.log('Image Url : ' + response.url)
                        console.log('\n');
                    }       
                }
            };
    

    【讨论】:

      猜你喜欢
      • 2012-08-28
      • 1970-01-01
      • 2022-01-20
      • 2020-06-08
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 1970-01-01
      相关资源
      最近更新 更多