JS 图像刮刀

Posted

技术标签:

【中文标题】JS 图像刮刀【英文标题】:JS Image scraper 【发布时间】:2021-10-19 15:26:09 【问题描述】:

我认为制作一个基本的图像抓取工具会是一个有趣的项目。下面的代码在网站上的控制台中工作,但我不知道如何从我的 app.js 中让它工作。

var anchors = document.getElementsByTagName('a');
var hrefs = [];
for(var i=0; i < anchors.length; i++) 
var src = anchors[i].href;
  if(src.endsWith(".jpeg")) 
    hrefs.push(anchors[i].href);
 console.log(hrefs);

我认为使用 puppeteer 是个好主意,但我的知识太有限,无法确定这是否正确。这是我的木偶代码:

const puppeteer = require("puppeteer");

async function scrape(url) 
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(url);

    var anchors = await page.evaluate(() => document.getElementsByTagName('a'));   
    
    var hrefs = [];
    for(var i=0; i < anchors.length; i++) var img = anchors[i].href;
      if(img.endsWith(".jpeg")) 
        hrefs.push(anchors[i].href);
     console.log(hrefs, img);
    
    browser.close();

我知道代码的最后一部分是错误的,但我找不到确切的答案来代替写什么。

感谢您抽出宝贵时间。

【问题讨论】:

【参考方案1】:

page.evaluate() 只能传输可序列化的值(大致是 JSON 可以处理的值)。由于document.getElementsByTagName() 返回一个不可序列化的 DOM 元素集合(它们包含方法和循环引用),所以集合中的每个元素都被替换为一个空对象。您需要返回可序列化的值(例如,文本数组或href 属性)或使用page.$$(selector)ElementHandle API 之类的东西。

Web API 没有在 .evaluate() 参数函数之外定义,因此您需要将所有 Web API 部分放在 .evaluate() 参数函数中并从中返回可序列化的数据。

const puppeteer = require("puppeteer");

async function scrape(url) 
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(url);

    const data = await page.evaluate(() => 
        const anchors = document.getElementsByTagName('a');
        const hrefs = [];
        for (let i = 0; i < anchors.length; i++) 
            const img = anchors[i].href;
            if (img.endsWith(".jpeg")) 
                hrefs.push(img);
            
        
        return hrefs;
    );
    console.log(data);

    await browser.close();

【讨论】:

以上是关于JS 图像刮刀的主要内容,如果未能解决你的问题,请参考以下文章

javascript 完整的完整网站刮板具有更多功能,易于使用的库;非js刮刀

使用 vue.js 在图像上传时保存图像类型

Next.Js 图像组件不会在 localhost 上加载图像

将资产图像路径作为动态内联样式背景图像 url (Nuxt.js)

如何在timeline.js的标志中添加图像

node.js - 将图像缓存到文件系统并将图像通过管道传输到响应