javascript - 抓取通过 JavaScript 呈现的网页。 PhantomJs 或任何其他工具?

标签 javascript html web-crawler phantomjs

我正在构建一个工具来抓取页面并将其 html 存储在本地。

还可以使用 iframe 在网页上加载该 HTML。所以我在抓取的页面上有取消绑定(bind)和绑定(bind)事件。

我正在使用 PhantomJS 获取网页数据。

通过 JavaScript 呈现数据的网页无法抓取。 PhantomJs 有什么办法可以做到这一点吗?

使用 PhantomJs 加载页面后获取网页数据的代码是:

shell 执行 phantomJs 命令的 PHP 代码

$shelldata = exec(PHATOM_JS_PATH."bin/phantomjs ".PHATOM_JS_PATH."/phantomcode.js $WEB_URL > webpage.html 2>&1");

示例 1

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

page.onLoadFinished = function(status) {
//  console.log('Status: ' + status);
    console.log(page.content);
    phantom.exit();
};

if(args.length > 1){
    page.open(args[1], function(status) {
        if(status == "success"){
        }else{
            console.log("Invalid");
            phantom.exit();
        }
    });

}else{
    console.log("Invalid");
    phantom.exit();
}

示例 2

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

if(args.length > 1){
    page.open(args[1], function(status) {
        if(status == "success"){
            setTimeout(function() {
                console.log(page.content);
                phantom.exit();
            }, 200);
        }else{
            console.log("Invalid");
            phantom.exit();
        }
    });
}else{
    console.log("Invalid");
    phantom.exit();
}

最佳答案

与其使用 200 毫秒的 SetTimeout,我认为将向下滚动脚本注入(inject)到您要下载的网站会更好,这就是避免网站使用窗口化

的方法

这是一个用 puppeteer 制作的例子用节点写

const puppeteer = require("puppeteer");
const fs = require("fs");

const injectionPath = "scrollInjection.js";

const writeContent = (content)=>{
  fs.writeFile("./test/pageoutput", content, function(err) {
    if(err) {
        return console.log(err);
    }
    console.log("The file was saved!");
}); 
}


const delay = time => {
  return new Promise(function(resolve) {
    setTimeout(resolve, time);
  });
};

let run = async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  //wait for page to fully loaded
  await page.goto(
    "URL TO GO TO"
  );

  //inject scrolling down script
  await page
    .evaluate(fs.readFileSync(injectionPath, "utf8"))
    .catch(err => console.log(err));

  //scroll down for x sec
  await delay("HOW MUCH TIME TO SCROLL DOWN THE PAGE ");

  // get page content
  const html = await page.content();
  writeContent(html)
  await browser.close();
};
run();

注入(inject)文件.js

function myTimer() {
  window.scrollTo(0, document.body.scrollHeight);
}
var scroller = setInterval(function() {
    myTimer();
  }, 1000);

关于javascript - 抓取通过 JavaScript 呈现的网页。 PhantomJs 或任何其他工具?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55492199/

相关文章:

javascript - 如何在javascript中找到第一个未定义的数组元素,并填充它?

web-scraping - 爬取和抓取特别困难的网站?

c# - 如何用ASP Core运行爬虫、服务交互和生命周期问题

javascript - 数据库日期和 jquery 日期验证

javascript - $_SESSION 在 AJAX 请求上丢失

javascript - 如何平滑地垂直移动/动画 DIV 背景图像?

javascript - 在两个div之间分割html?

html - 如何在grails messages.properties中使用HTML发送邮件

html - 如何从坐标获取 CSS 的左、上、宽、高?

javascript - 在本地主机上为meteor.js 设置 prerender.io