【问题标题】:How to obtain a pdf embedded in page through puppeteer?如何通过puppeteer获取嵌入页面的pdf?
【发布时间】:2018-04-24 20:08:17
【问题描述】:

我正在尝试获取结构如下的页面的 pdf 副本:

<body style="background-color: rgb(38,38,38); height: 100%; width: 100%; overflow: hidden; margin: 0">
    <embed width="100%" height="100%" name="plugin" id="plugin" src="https://www.thesourceurl.com" type="application/pdf" internalinstanceid="7" title="">
</body>

我尝试使用 page.pdf 获取它,但我得到了一个空白 pdf,中间写着“无法加载插件”。

【问题讨论】:

  • 为什么不直接抓取源码呢?
  • @TuanAnhTran 源网址与我导航到的网址相同!如果你能理解我想说的话,他们已经嵌入了我导航到的页面,就像递归一样。
  • 嵌入中的源代码是这样的https://www.thesourceurl.com/somepdf.pdf 吗?
  • @Rippo 不,这是一个很长的字符串,在任何地方都没有 .pdf
  • 现在我发现这是 puppeteer 中的一个错误,它无法以无头错误模式呈现嵌入任何形式的 pdf 的链接。任何其他建议表示赞赏。

标签: javascript node.js puppeteer


【解决方案1】:

对于偶然发现这个问题的其他人,

在撰写本文时,这是 chromium 中的一个已知错误,您无法在 headless:true 模式下导航到 pdf 或嵌入 pdf 的页面。

我找到了这个here 的临时解决方案,但您必须事先知道获取 pdf 的网址。

page.exposeFunction("writeABString", async (strbuf, targetFile) => {

        var str2ab = function _str2ab(str) { // Convert a UTF-8 String to an ArrayBuffer

            var buf = new ArrayBuffer(str.length); // 1 byte for each char
            var bufView = new Uint8Array(buf);

            for (var i=0, strLen=str.length; i < strLen; i++) {
              bufView[i] = str.charCodeAt(i);
            }
            return buf;
        }

        console.log("In 'writeABString' function...");

        return new Promise((resolve, reject) => {

            // Convert the ArrayBuffer string back to an ArrayBufffer, which in turn is converted to a Buffer
            let buf = Buffer.from(str2ab(strbuf));

            // Try saving the file.        
            fs.writeFile(targetFile, buf, (err, text) => {
                if(err) reject(err);
                else resolve(targetFile);
            });
        });
    });

在上一页中,您必须使用评估调用获取 pdf 并获取 api 以最初获取缓冲区响应并进行转换:

page.evaluate( async () => { 

    function arrayBufferToString(buffer){ // Convert an ArrayBuffer to an UTF-8 String

        var bufView = new Uint8Array(buffer);
        var length = bufView.length;
        var result = '';
        var addition = Math.pow(2,8)-1;

        for(var i = 0;i<length;i+=addition){
            if(i + addition > length){
                addition = length - i;
            }
            result += String.fromCharCode.apply(null, bufView.subarray(i,i+addition));
        }
        return result;
    }

   let geturl = "https://whateverurl.example.com";

   return fetch(geturl, {
       credentials: 'same-origin', // usefull when we are logged into a website and want to send cookies
       responseType: 'arraybuffer', // get response as an ArrayBuffer
   })
   .then(response => response.arrayBuffer())
   .then( arrayBuffer => {
       var bufstring = arrayBufferToString(arrayBuffer);
       return window.writeABString(bufstring, '/tmp/downloadtest.pdf');
   })
   .catch(function (error) {
       console.log('Request failed: ', error);
   }); 
 });

【讨论】:

    【解决方案2】:

    这似乎是 Puppeteer 中的一个错误。它肯定曾经在早期版本中工作过。

    见https://github.com/GoogleChrome/puppeteer/issues/1872

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 2019-05-13
      • 1970-01-01
      • 2014-11-26
      • 2020-09-24
      相关资源
      最近更新 更多