คำตอบด่วน
ฉันใช้พร็อกซีหมุนเวียนใน Node.js อย่างไร?
กับ fetch สร้าง undici ProxyAgent สำหรับ http://gw.crawlrelay.com:7777 แล้วส่งเป็น dispatcher กับ axios หรือ got ส่ง proxy agent เช่น https-proxy-agent หรือ hpagent และตั้งค่า proxy: false ใน axios CrawlRelay มีพร็อกซีเรซิเดนเชียลอ่านประเทศและเซสชันจากชื่อผู้ใช้ จาก US$0.50/GB จ่ายด้วยคริปโต ไม่ต้อง KYC
ตั้งค่า Node.js แบบคร่าว ๆ
| fetch / undici | new ProxyAgent({ uri, token }), แล้ว fetch(url, { dispatcher }) |
|---|---|
| axios | httpsAgent: new HttpsProxyAgent(url) และ proxy: false |
| got | agent: { https: new HttpsProxyAgent({ proxy }) } จาก hpagent |
| SOCKS5 | socks-proxy-agent กับ URL แบบ socks5h:// บนพอร์ต 7778 |
| IP ใหม่ทุกคำขอ | เอเจนต์ใหม่หรือ session ID ใหม่ทุกคำขอ; การเชื่อมต่อแบบ pooled จะรักษา exit เดิมไว้ |
| รูปแบบโมดูล | ตัวอย่างคือ ES modules (.mjs หรือ "type": "module") ที่ใช้ top-level await |
ฉันจะใช้พร็อกซีกับ fetch ของ Node อย่างไร?
fetch แบบ global ใน Node fetch สร้างบน undici แต่เริ่มต้นไม่รองรับ HTTP_PROXY หรือ HTTPS_PROXY ติดตั้ง undici แล้วส่ง ProxyAgent เป็น dispatcher ฟิลด์ token จะส่งข้อมูลรับรองเป็น header Proxy-Authorization ดังนั้นรหัสผ่านจะไม่ปรากฏใน URL ที่อาจถูกบันทึกไว้
import { ProxyAgent, fetch } from "undici";
const credentials = Buffer.from("USERNAME-country-us:PASSWORD").toString("base64");
const dispatcher = new ProxyAgent({
uri: "http://gw.crawlrelay.com:7777",
token: `Basic ${credentials}`,
});
const res = await fetch("https://api.ipify.org?format=json", {
dispatcher,
signal: AbortSignal.timeout(30000),
});
console.log(res.status, await res.json());
await dispatcher.close();ฉันจะใช้พร็อกซีกับ axios อย่างไร?
อย่าใช้ตัวเลือก proxy ของ axios กับเว็บ HTTPS: มันส่งคำขอไปยังพร็อกซีโดยไม่มีการเปิด tunnel CONNECT ซึ่งพร็อกซีหลายแห่งจะปฏิเสธ ปิดใช้งานด้วย proxy: false แล้วส่ง agent ที่เปิด tunnel แบบถูกต้อง
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("http://USERNAME-country-de:[email protected]:7777");
const client = axios.create({ httpsAgent: agent, httpAgent: agent, proxy: false, timeout: 30000 });
const { data } = await client.get("https://api.ipify.org?format=json");
console.log(data.ip);ฉันจะใช้พร็อกซีกับ got อย่างไร?
got ใช้ agent หนึ่งตัวต่อโปรโตคอล hpagent ปฏิบัติตาม http.Agent ของ Node: ปิด keep-alive เว้นแต่คุณจะส่ง keepAlive: true ปล่อยให้ปิด หรือกำหนด keepAlive: false ตามด้านล่าง เมื่อคุณต้องการให้แต่ละคำขอใช้การเชื่อมต่อใหม่ และโดยปกติจะเป็น exit ใหม่
import got from "got";
import { HttpsProxyAgent } from "hpagent";
const proxy = "http://USERNAME-country-fr:[email protected]:7777";
const body = await got("https://api.ipify.org", {
agent: { https: new HttpsProxyAgent({ proxy, keepAlive: false }) },
timeout: { request: 30000 },
retry: { limit: 2, statusCodes: [429, 502, 503, 504] },
}).text();
console.log(body);ฉันจะใช้ SOCKS5 ใน Node.js อย่างไร?
ใช้ socks-proxy-agent กับ scheme socks5h:// เพื่อให้ hostname ถูกแปลงที่ exit ทำงานกับโมดูล http และ https ของ Node และกับไลบรารีใดๆ ที่รับ agent
import https from "node:https";
import { SocksProxyAgent } from "socks-proxy-agent";
const agent = new SocksProxyAgent("socks5h://USERNAME-country-gb:[email protected]:7778");
const req = https.get("https://api.ipify.org", { agent, timeout: 30000 }, (res) => {
let body = "";
res.on("data", (chunk) => (body += chunk));
res.on("end", () => console.log(res.statusCode, body));
});
req.on("timeout", () => req.destroy(new Error("timeout after 30 s")));
req.on("error", (err) => console.error(err.code, err.message));ฉันจะจำกัดความพร้อมกันต่อโฮสต์โดยไม่ใช้ไลบรารีได้อย่างไร?
Promise.all กับ URLs กว่า 10,000 รายการ จะเปิด 10,000 คำขอพร้อมกัน ตัวจำกัดขนาดเล็กต่อ hostname จะช่วยให้แต่ละไซต์อยู่ในระดับที่สุภาพขณะที่การรวบรวมทำงานแบบขนาน โค้ดด้านล่างไม่พึ่งพาอะไรและทำงานกับไคลเอนต์ใดๆ ที่กล่าวมา
import { ProxyAgent, fetch } from "undici";
const PER_HOST = 4;
const active = new Map();
const waiting = new Map();
const dispatcher = new ProxyAgent("http://USERNAME-country-us:[email protected]:7777");
async function withHostSlot(url, task) {
const host = new URL(url).hostname;
while ((active.get(host) ?? 0) >= PER_HOST) {
await new Promise((resolve) => {
if (!waiting.has(host)) waiting.set(host, []);
waiting.get(host).push(resolve);
});
}
active.set(host, (active.get(host) ?? 0) + 1);
try {
return await task();
} finally {
active.set(host, active.get(host) - 1);
waiting.get(host)?.shift()?.();
}
}
const urls = ["https://example.com/", "https://example.org/", "https://example.net/"];
const results = await Promise.all(
urls.map((url) =>
withHostSlot(url, async () => {
const res = await fetch(url, { dispatcher, signal: AbortSignal.timeout(30000) });
return [url, res.status, (await res.arrayBuffer()).byteLength];
}).catch((err) => [url, err.name, 0])
)
);
console.table(results);
await dispatcher.close();ทำไมฉันถึงได้ IP เดิมสองครั้ง หรือเกิด ECONNRESET?
Agents รวบรวมการเชื่อมต่อ และการเชื่อมต่อ pooled จะรักษา exit ที่เปิดไว้ สำหรับ IP ใหม่ในแต่ละคำขอ สร้าง agent ใหม่ต่อคำขอแล้วปิดหลังใช้ ปิด keep-alive ใน agent หรือใส่ -session-<id> เฉพาะใน username ของแต่ละคำขอ
ECONNRESET และ socket hang up มักเกิดจากการใช้ซ็อกเก็ต pooled ที่อีกฝ่ายปิดไปแล้ว หรือ exit ที่หลุด ลองส่งคำขอ GET ใหม่อีกครั้งด้วยการเชื่อมต่อใหม่ หน้าการรีเซ็ตการเชื่อมต่อ อธิบายรายละเอียด]
คำถามเกี่ยวกับ Node.js และพร็อกซี
Node.js fetch รองรับ HTTP_PROXY หรือไม่?
ไม่ใช่โดยค่าเริ่มต้นในเวอร์ชันที่โปรเจกต์ส่วนใหญ่นิยมใช้ตอนนี้: fetch แบบ global จะไม่สนใจตัวแปรสภาพแวดล้อมพร็อกซีถ้าไม่ส่ง dispatcher ใช้ undici ProxyAgent ตามตัวอย่างด้านบน หรือกำหนด global dispatcher ด้วย undici setGlobalDispatcher() ถ้าต้องการให้ทุกคำขอในโปรเซสใช้พร็อกซี
ทำไม axios ถึงล้มเหลวกับเว็บ HTTPS ที่อยู่หลังพร็อกซี?
ตัวเลือก proxy ในตัวของ axios ส่งคำขอ HTTPS ไปยังพร็อกซีในรูปแบบที่พร็อกซีหลายแห่งไม่ยอมรับ แทนที่จะเปิด tunnel CONNECT ให้ตั้ง proxy: false และส่ง HttpsProxyAgent เป็น httpsAgent จากนั้นคำขอจะวิ่งผ่าน tunnel ที่ถูกต้อง และ TLS จะอยู่ระหว่างโค้ดของคุณกับเว็บไซต์
ฉันจะส่งคำขอจากหลายประเทศใน Node.js process เดียวได้อย่างไร?
สร้าง agent หนึ่งตัวต่อประเทศ แต่ละตัวมี username ของตัวเอง เช่น USERNAME-country-de หรือ USERNAME-country-jp แล้วเลือก agent ตามคำขอ Agents ใช้งานง่ายและถูก และแยกกันเก็บ pool การเชื่อมต่อและ exit ของแต่ละ agent
ฉันควรกำหนด timeout ไหนใน Node.js?
ควรกำหนดทุกครั้ง: AbortSignal.timeout(30000) สำหรับ fetch, timeout: 30000 สำหรับ axios, timeout: { request: 30000 } สำหรับ got สามสิบวินาทีเหมาะกับหน้า HTML เป้าหมายช้าและ exit มือถือให้เวลาถึง 60 วินาที และลองใหม่ด้วยการเชื่อมต่อใหม่แทนการรอนานกว่า
เชื่อมต่อเครื่องรวบรวมข้อมูล Node.js ของคุณ
US$5.94 สำหรับ 10 GB, US$0.50/GB จาก 50 GB.