我如何 运行 多次使用一个脚本并存储值,然后使用 google-search-results-nodejs 客户端将其发送到前端
how can i run one script for multiple times and store value then send it to frontend using google-search-results-nodejs client
假设我有 10 个关键字 kewords1、keyword2。我想 运行 这个脚本用于所有带有 mern 堆栈的关键字,然后将这个响应发送到前端反应。请让我知道我该怎么做?
这是简单的代码。
const SerpApi = require('google-search-results-nodejs')
const search = new SerpApi.GoogleSearch("Your Private Key")
search.json({
q: "Coffee",
location: "Austin, TX"
}, (result) => {
console.log(result)
})
我不知道您要求帮助实现应用程序的哪一部分。以下是后端和前端部分。
后端
const express = require("express");
const { GoogleSearch } = require("google-search-results-nodejs");
const search = new GoogleSearch(process.env.API_KEY);
const app = express();
app.set('json spaces', 2)
app.use(express.json());
// Set routes
app.get("/", (req, res) => {
res.send("Make a request to /search?q=coffee&q=cake");
});
app.get("/search", (req, res) => {
// The number of queries should be limited in a real application
// but it's ommitted here in favor of simplicity
const queries = Array.from(req.query.q);
makeSearches(queries).then((results) => {
res.send(results);
});
});
// API
// Workaround to make it work with Promises
// https://github.com/serpapi/google-search-results-nodejs/issues/4
function promisifiedGetJson(params) {
return new Promise((resolve, reject) => {
try {
search.json(params, resolve);
} catch (e) {
reject(e);
}
});
}
function makeSearches(queries) {
const promises = queries.map((q) => {
const params = {
q,
location: "Austin, TX",
};
return promisifiedGetJson(params);
});
return Promise.all(promises);
};
// Start server
app.listen(3000, () => {
console.log(`Server is running on port: 3000`);
});
示例请求和响应:
$ curl -s 'https://mern-serpapi-nodejs.serpapi.repl.co/search?q=Whosebug&q=github&q=deno' | jq -r '.[].search_metadata'
{
"id": "61fad426607393485726c241",
"status": "Success",
"json_endpoint": "https://serpapi.com/searches/582d9fcdfd66a739/61fad426607393485726c241.json",
"created_at": "2022-02-02 18:57:42 UTC",
"processed_at": "2022-02-02 18:57:42 UTC",
"google_url": "https://www.google.com/search?q=Whosebug&oq=Whosebug&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8",
"raw_html_file": "https://serpapi.com/searches/582d9fcdfd66a739/61fad426607393485726c241.html",
"total_time_taken": 0.66
}
{
"id": "61fad42617f923aa08188dfc",
"status": "Success",
"json_endpoint": "https://serpapi.com/searches/667255ede060a7ae/61fad42617f923aa08188dfc.json",
"created_at": "2022-02-02 18:57:42 UTC",
"processed_at": "2022-02-02 18:57:42 UTC",
"google_url": "https://www.google.com/search?q=github&oq=github&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8",
"raw_html_file": "https://serpapi.com/searches/667255ede060a7ae/61fad42617f923aa08188dfc.html",
"total_time_taken": 0.96
}
{
"id": "61fad4261baebbb454181a3a",
"status": "Success",
"json_endpoint": "https://serpapi.com/searches/ae665860b250fd5f/61fad4261baebbb454181a3a.json",
"created_at": "2022-02-02 18:57:42 UTC",
"processed_at": "2022-02-02 18:57:42 UTC",
"google_url": "https://www.google.com/search?q=deno&oq=deno&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8",
"raw_html_file": "https://serpapi.com/searches/ae665860b250fd5f/61fad4261baebbb454181a3a.html",
"total_time_taken": 0.61
}
说明
答案由两部分组成:使用 SerpApi 发出 N 个请求和 return 响应。
发出 N 个请求
目前,google-search-results-nodejs
没有 Promise API 所以 the workaround to make it work with Promises is required. With callback API it's also possible but it requires the usage of Array#reduce.
function promisifiedGetJson(params) {
return new Promise((resolve, reject) => {
try {
search.json(params, resolve);
} catch (e) {
reject(e);
}
});
}
使用 Promise API,关键字列表将映射到 Promise 数组。
function makeSearches(queries) {
const promises = queries.map((q) => {
const params = {
q,
location: "Austin, TX",
};
return promisifiedGetJson(params);
});
return Promise.all(promises);
};
API 到 return 响应的操作(路由)
它获取一个查询参数数组并调用一个 makeSearches
函数。
app.get("/search", (req, res) => {
// The number of queries should be limited in a real application
// but it's ommitted here in favor of simplicity
const queries = Array.from(req.query.q);
makeSearches(queries).then((results) => {
res.send(results);
});
});
Front-end部分
这里有两个 full-stack React 项目,它们使用上面的 API。
- Next.js app repository. Preview: nextjs-serpapi.vercel.app
- Express.js app repository. Preview: https://express-react-serpapi.vercel.app
演示
https://user-images.githubusercontent.com/282605/155405202-50bceacb-57f6-4729-b950-ea6e5ef6c295.mp4
两个项目都部署到 Vercel。 Next.js 应用更简单,因为这是 Next.js 的价值主张。
Express.js 应用仅在开发模式下具有 SSR。它使用 Vite 在服务器上渲染 React 组件。 Next.js 应用在开发和生产中有 SSR。
React 组件本身在这两种情况下是相同的:
// App.jsx
import React from "react";
import ReactDOM from "react-dom";
import React, { useState } from "react";
import { SearchResults } from "./SearchResults";
export function App() {
const [q, setQ] = useState("coffee, cats");
const [searchResults, setSearchResults] = useState([]);
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
function handleFormSubmit(event) {
event.preventDefault();
const params = new URLSearchParams({
q,
});
setLoading(true);
fetch(`/api/search?${params}`)
.then((res) => res.json())
.then(
(results) => {
setSearchResults(results);
setLoading(false);
setError(null);
},
(error) => {
setError(error);
}
);
}
function handleQChange(event) {
event.preventDefault();
setQ(event.target.value);
}
return (
<>
<h1>SerpApi example in MERN stack</h1>
<form action="/api/search" method="get" onSubmit={handleFormSubmit}>
<label>
<label>Queries (separated by comma):</label>
<input name="q" value={q} placeholder={q} onChange={handleQChange} />
<br />
<input
type="submit"
value={isLoading ? "Loading..." : "Search"}
disabled={isLoading} />
</label>
</form>
<br />
<SearchResults
results={searchResults}
isLoading={isLoading}
error={error} />
</>
);
}
ReactDOM.hydrate(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
SearchResults.jsx
function SearchResults({ results, isLoading, error }) {
if (isLoading)
return (
<p>
Loading...
</p>
);
if (!results || results.length === 0) {
return <p>Click "Search" ↑ to continue.</p>;
}
if (error) return <p>Error: {error}</p>;
return (
<section>
<h3>Search results ({results.length})</h3>
<ul>{results.map(r => (<li key={r.search_metadata.id}>{r.search_metadata.id}</li>))}</ul>
</section>
);
}
免责声明:我在 SerpApi 工作。
这个问题在 Github repository of google-search-results-nodejs
出现在这里的前一天被问到。
假设我有 10 个关键字 kewords1、keyword2。我想 运行 这个脚本用于所有带有 mern 堆栈的关键字,然后将这个响应发送到前端反应。请让我知道我该怎么做?
这是简单的代码。
const SerpApi = require('google-search-results-nodejs')
const search = new SerpApi.GoogleSearch("Your Private Key")
search.json({
q: "Coffee",
location: "Austin, TX"
}, (result) => {
console.log(result)
})
我不知道您要求帮助实现应用程序的哪一部分。以下是后端和前端部分。
后端
const express = require("express");
const { GoogleSearch } = require("google-search-results-nodejs");
const search = new GoogleSearch(process.env.API_KEY);
const app = express();
app.set('json spaces', 2)
app.use(express.json());
// Set routes
app.get("/", (req, res) => {
res.send("Make a request to /search?q=coffee&q=cake");
});
app.get("/search", (req, res) => {
// The number of queries should be limited in a real application
// but it's ommitted here in favor of simplicity
const queries = Array.from(req.query.q);
makeSearches(queries).then((results) => {
res.send(results);
});
});
// API
// Workaround to make it work with Promises
// https://github.com/serpapi/google-search-results-nodejs/issues/4
function promisifiedGetJson(params) {
return new Promise((resolve, reject) => {
try {
search.json(params, resolve);
} catch (e) {
reject(e);
}
});
}
function makeSearches(queries) {
const promises = queries.map((q) => {
const params = {
q,
location: "Austin, TX",
};
return promisifiedGetJson(params);
});
return Promise.all(promises);
};
// Start server
app.listen(3000, () => {
console.log(`Server is running on port: 3000`);
});
示例请求和响应:
$ curl -s 'https://mern-serpapi-nodejs.serpapi.repl.co/search?q=Whosebug&q=github&q=deno' | jq -r '.[].search_metadata'
{
"id": "61fad426607393485726c241",
"status": "Success",
"json_endpoint": "https://serpapi.com/searches/582d9fcdfd66a739/61fad426607393485726c241.json",
"created_at": "2022-02-02 18:57:42 UTC",
"processed_at": "2022-02-02 18:57:42 UTC",
"google_url": "https://www.google.com/search?q=Whosebug&oq=Whosebug&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8",
"raw_html_file": "https://serpapi.com/searches/582d9fcdfd66a739/61fad426607393485726c241.html",
"total_time_taken": 0.66
}
{
"id": "61fad42617f923aa08188dfc",
"status": "Success",
"json_endpoint": "https://serpapi.com/searches/667255ede060a7ae/61fad42617f923aa08188dfc.json",
"created_at": "2022-02-02 18:57:42 UTC",
"processed_at": "2022-02-02 18:57:42 UTC",
"google_url": "https://www.google.com/search?q=github&oq=github&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8",
"raw_html_file": "https://serpapi.com/searches/667255ede060a7ae/61fad42617f923aa08188dfc.html",
"total_time_taken": 0.96
}
{
"id": "61fad4261baebbb454181a3a",
"status": "Success",
"json_endpoint": "https://serpapi.com/searches/ae665860b250fd5f/61fad4261baebbb454181a3a.json",
"created_at": "2022-02-02 18:57:42 UTC",
"processed_at": "2022-02-02 18:57:42 UTC",
"google_url": "https://www.google.com/search?q=deno&oq=deno&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8",
"raw_html_file": "https://serpapi.com/searches/ae665860b250fd5f/61fad4261baebbb454181a3a.html",
"total_time_taken": 0.61
}
说明
答案由两部分组成:使用 SerpApi 发出 N 个请求和 return 响应。
发出 N 个请求
目前,google-search-results-nodejs
没有 Promise API 所以 the workaround to make it work with Promises is required. With callback API it's also possible but it requires the usage of Array#reduce.
function promisifiedGetJson(params) {
return new Promise((resolve, reject) => {
try {
search.json(params, resolve);
} catch (e) {
reject(e);
}
});
}
使用 Promise API,关键字列表将映射到 Promise 数组。
function makeSearches(queries) {
const promises = queries.map((q) => {
const params = {
q,
location: "Austin, TX",
};
return promisifiedGetJson(params);
});
return Promise.all(promises);
};
API 到 return 响应的操作(路由)
它获取一个查询参数数组并调用一个 makeSearches
函数。
app.get("/search", (req, res) => {
// The number of queries should be limited in a real application
// but it's ommitted here in favor of simplicity
const queries = Array.from(req.query.q);
makeSearches(queries).then((results) => {
res.send(results);
});
});
Front-end部分
这里有两个 full-stack React 项目,它们使用上面的 API。
- Next.js app repository. Preview: nextjs-serpapi.vercel.app
- Express.js app repository. Preview: https://express-react-serpapi.vercel.app
演示
https://user-images.githubusercontent.com/282605/155405202-50bceacb-57f6-4729-b950-ea6e5ef6c295.mp4
两个项目都部署到 Vercel。 Next.js 应用更简单,因为这是 Next.js 的价值主张。
Express.js 应用仅在开发模式下具有 SSR。它使用 Vite 在服务器上渲染 React 组件。 Next.js 应用在开发和生产中有 SSR。
React 组件本身在这两种情况下是相同的:
// App.jsx
import React from "react";
import ReactDOM from "react-dom";
import React, { useState } from "react";
import { SearchResults } from "./SearchResults";
export function App() {
const [q, setQ] = useState("coffee, cats");
const [searchResults, setSearchResults] = useState([]);
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState(null);
function handleFormSubmit(event) {
event.preventDefault();
const params = new URLSearchParams({
q,
});
setLoading(true);
fetch(`/api/search?${params}`)
.then((res) => res.json())
.then(
(results) => {
setSearchResults(results);
setLoading(false);
setError(null);
},
(error) => {
setError(error);
}
);
}
function handleQChange(event) {
event.preventDefault();
setQ(event.target.value);
}
return (
<>
<h1>SerpApi example in MERN stack</h1>
<form action="/api/search" method="get" onSubmit={handleFormSubmit}>
<label>
<label>Queries (separated by comma):</label>
<input name="q" value={q} placeholder={q} onChange={handleQChange} />
<br />
<input
type="submit"
value={isLoading ? "Loading..." : "Search"}
disabled={isLoading} />
</label>
</form>
<br />
<SearchResults
results={searchResults}
isLoading={isLoading}
error={error} />
</>
);
}
ReactDOM.hydrate(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
SearchResults.jsx
function SearchResults({ results, isLoading, error }) {
if (isLoading)
return (
<p>
Loading...
</p>
);
if (!results || results.length === 0) {
return <p>Click "Search" ↑ to continue.</p>;
}
if (error) return <p>Error: {error}</p>;
return (
<section>
<h3>Search results ({results.length})</h3>
<ul>{results.map(r => (<li key={r.search_metadata.id}>{r.search_metadata.id}</li>))}</ul>
</section>
);
}
免责声明:我在 SerpApi 工作。
这个问题在 Github repository of google-search-results-nodejs
出现在这里的前一天被问到。