Web Scraping с Puppeteer + Next. js и Express - PullRequest
0 голосов
/ 18 февраля 2020

Попытка выяснить, почему моя функция очистки выполняется дважды. Я пытаюсь создать приложение SSR, которое попадает на веб-сайт и очищает данные. Он работает и правильно захватывает нужные мне данные, но я установил безглавый на false, и я вижу, что браузер правильно открывается, а затем снова открывается и ищет термин [object Object] ...

Мне нужно только запустить на сервере, поэтому я пошел express + следующий. js комбо.

сервер. js

const express = require("express");
const next = require("next");
const scraper = require("./utils/scraper");

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const nextApp = next({ dev });
const nextHandle = nextApp.getRequestHandler();

nextApp.prepare().then(() => {
  const server = express();

  server.get("/search/:query", async (req, res) => {
    const { query } = req.params;

    const listings = await scraper.scrape(query);

    return nextApp.render(req, res, "/search", { search: query, listings });
  });

  server.get("*", (req, res) => {
    return nextHandle(req, res);
  });

  server.listen(port, err => {
    if (err) {
      throw err;
    }
    console.log(`> Ready on http://localhost:${port}`);
  });
});

скребок. js

const puppeteer = require("puppeteer");

const scrape = async term => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto(`https://...&query=${term}`);

  const scrapedData = await page.evaluate(() => {
    const items = document.querySelectorAll(".results");
    return Array.from(items).map(listing => {
      return { ... build up my obj here };
    });
  });

  await browser.close();
  return scrapedData;
};

module.exports.scrape = scrape;

Search.jsx (следующая. js страница)

import React, { Component } from "react";

export default class extends Component {
  static async getInitialProps(ctx) {
    return {
      search: ctx.query.search,
      listings: ctx.query.listings
    };
  }

  render() {
    const { search, listings } = this.props;
    console.log(listings, "client");
    return (
      <div>
        <h1>{search} search!</h1>
        { ...listings.map() }
      </div>
    );
  }
}

ОБНОВЛЕНИЕ 1 Я заметил, что кукловод будет правильно открываться только один раз, если я не передам свой listings массив в nextApp.render и просто выйдите из результатов на сервере. Но как только я передаю его на страницу getInitialProps, я испытываю двойную загрузку, как описано выше.

...