nodeJS搭建免费代理IP池爬取贴吧图片实战

2023-12-30 07:44

本文主要是介绍nodeJS搭建免费代理IP池爬取贴吧图片实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前用python写过爬虫,这次想试试nodeJS爬虫爬取贴吧图片,话不多说代码如下,爬取制定吧的前十页所有帖子里的图片

 爬取贴吧图片脚本

你得提前创建一个images文件夹

const axios = require("axios");
const cheerio = require("cheerio");
const sanitize = require("sanitize-filename");
const fs = require("fs");
const path = require("path");// 定义要爬取的贴吧URL
const baseUrl = "https://tieba.baidu.com/f?kw=%CB%EF%D0%A6%B4%A8&fr=ala0&tpl=5&dyTabStr=MCwxLDMsMiw2LDQsNSw4LDcsOQ%3D%3D";// 发送HTTP请求获取页面内容
async function getTitlesByPage(pageNum) {const url = baseUrl + pageNum * 50;try {const response = await axios.get(url);if (response.status === 200) {// 使用cheerio解析页面const $ = cheerio.load(response.data);$(".threadlist_title a.j_th_tit").each((index, element) => {// 定义要下载的帖子URLconst url = "https://jump2.bdimg.com" + $(element).attr("href");// 发送HTTP请求获取页面内容axios.get(url).then((response) => {if (response.status === 200) {// 使用cheerio解析页面const $ = cheerio.load(response.data);// 获取帖子中的所有图片链接const imgUrls = [];$("img.BDE_Image").each((index, element) => {imgUrls.push($(element).attr("src"));});// 下载所有图片imgUrls.forEach((imgUrl, index) => {axios({method: "get",url: imgUrl,responseType: "stream",headers: {Referer: url,},}).then((response) => {const filename = sanitize(path.basename(imgUrl));const filePath = path.resolve(__dirname,`./images/${filename}.jpg`);response.data.pipe(fs.createWriteStream(filePath));console.log(`第 ${index + 1} 张图片下载完成`);}).catch((error) => {console.log(`第 ${index + 1} 张图片下载失败`, error);});});} else {console.log("请求失败");}}).catch((error) => {console.log("请求出错", error);});});} else {console.log(`请求第 ${pageNum + 1} 页失败`);}} catch (error) {console.log(`请求第 ${pageNum + 1} 页出错`, error);}
}async function getTitles() {for (let i = 0; i < 10; i++) {await getTitlesByPage(i);}
}getTitles();

这里有个弊端,IP会被马上封掉,那么通过爬取免费代理IP网站的IP去创建本地代理IP池txt文件

找了一个勉强可用的免费代理IP网站免费代理IP_免费HTTP代理IP_SOCKS5代理服务器_优质IP代理_89免费代理IP

里面的有效IP很少,那么得自己去大量爬取筛选可用IP

 这个是

爬取建立免费代理IP池的脚本

你得提前创建一个proxy.txt文件

const fs = require('fs');
const axios = require('axios');
const cheerio = require('cheerio');const headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
};async function get89IP(filePath) {for (let i = 1; i <= 10; i++) { // 循环采集前10页的数据const url = `https://www.89ip.cn/index_${i}.html`;try {const response = await axios.get(url, { headers });const $ = cheerio.load(response.data);const trs = $('table tbody tr');trs.each((index, element) => {const ip = $(element).find('td:nth-child(1)').text().trim();const port = $(element).find('td:nth-child(2)').text().trim();const proxyIP = `${ip}:${port}`;fs.appendFileSync(filePath, proxyIP + '\n');});console.log(`第${i}页采集完成`);} catch (error) {console.error('出错了:', error);}await new Promise((resolve) => setTimeout(resolve, 1000));}
}async function main() {const filePath = './proxy.txt';while (true) {try {await get89IP(filePath);console.log('采集完成');} catch (error) {console.error('出错了:', error);}await new Promise((resolve) => setTimeout(resolve, 60000));}
}main();

 采集完成后的筛选IP代码

 一个一个筛选太慢,这里使用到了Promise.all

你得提前创建一个KyProxy.txt文件

const fs = require('fs');
const axios = require('axios');const proxyList = fs.readFileSync('proxy.txt', 'utf-8').split('\n').filter(Boolean);async function testProxy(ip) {try {const response = await axios.get('https://tieba.baidu.com/', {proxy: {host: ip.split(':')[0],port: ip.split(':')[1]},timeout: 5000});if (response.status === 200 || response.status === 302) {return true;}} catch (error) {console.error(error);}return false;
}async function main() {const promiseArr = [];for (const proxy of proxyList) {promiseArr.push(testProxy(proxy));}const resultArr = await Promise.all(promiseArr);const validProxies = resultArr.reduce((acc, curr, index) => {if (curr) {acc.push(proxyList[index]);console.log(`代理IP ${proxyList[index]} 可用`);} else {console.log(`代理IP ${proxyList[index]} 不可用`);}return acc;}, []);fs.writeFileSync('kyProxy.txt', validProxies.join('\n'));console.log('可用代理IP已写入 kyProxy.txt');
}main().catch((error) => console.error(error));

 到这一步kyProxy.txt里面的IP基本是稳定可用的了,最后一步就是使用kyProxy.txt里的代理I去爬取图片

 通过代理IP爬取贴吧图片

const axios = require("axios");
const cheerio = require("cheerio");
const sanitize = require("sanitize-filename");
const fs = require("fs");
const path = require("path");// 定义要爬取的贴吧URL
const baseUrl ="https://tieba.baidu.com/f?kw=%CB%EF%D0%A6%B4%A8&fr=ala0&tpl=5&dyTabStr=MCwxLDMsMiw2LDQsNSw4LDcsOQ%3D%3D";// 获取代理IP池
async function getProxyList() {const fileContent = await fs.promises.readFile(path.resolve(__dirname, "./kyProxy.txt"),"utf8");return fileContent.trim().split("\n");
}// 发送HTTP请求获取页面内容
async function getTitlesByPage(pageNum, proxyList) {const url = baseUrl + pageNum * 50;try {let success = false;for (let i = 0; i < proxyList.length; i++) {const proxy = `${proxyList[i]}`;console.log(`使用代理IP:${proxy}`);try {const response = await axios.get(url, {proxy: {host: proxyList[i].split(":")[0],port: proxyList[i].split(":")[1],},});if (response.status === 200) {// 使用cheerio解析页面const $ = cheerio.load(response.data);$(".threadlist_title a.j_th_tit").each(async (index, element) => {// 定义要下载的帖子URLconst url = "https://jump2.bdimg.com" + $(element).attr("href");// 发送HTTP请求获取页面内容const imgUrls = await getImgUrls(url, proxy);// 下载所有图片for (let j = 0; j < imgUrls.length; j++) {await downloadImg(imgUrls[j], j, url, proxy);}});success = true;break;} else {console.log(`代理IP ${proxy} 请求失败`);}} catch (error) {console.log(`代理IP ${proxy} 请求出错`, error);}}if (!success) {console.log(`请求第 ${pageNum + 1} 页失败,跳过`);}} catch (error) {console.log(`请求第 ${pageNum + 1} 页出错`, error);}
}// 获取帖子中的所有图片链接
async function getImgUrls(url, proxy) {try {const response = await axios.get(url, {proxy: {host: proxy.split(":")[0],port: proxy.split(":")[1],},headers: {Referer: url,},});if (response.status === 200) {const $ = cheerio.load(response.data);const imgUrls = [];$("img.BDE_Image").each((index, element) => {imgUrls.push($(element).attr("src"));});return imgUrls;} else {console.log(`请求 ${url} 失败`);return [];}} catch (error) {console.log(`请求 ${url} 出错`, error);return [];}
}// 下载单张图片
async function downloadImg(imgUrl, index, url, proxy) {try {const response = await axios({method: "get",url: imgUrl,responseType: "stream",proxy: {host: proxy.split(":")[0],port: proxy.split(":")[1],},headers: {Referer: url,},});if (response.status === 200) {const filename = sanitize(path.basename(imgUrl));const filePath = path.resolve(__dirname, `./images/${filename}.jpg`);response.data.pipe(fs.createWriteStream(filePath));console.log(`第 ${index + 1} 张图片下载完成`);} else {console.log(`第 ${index + 1} 张图片下载失败`);}} catch (error) {console.log(`第 ${index + 1} 张图片下载出错`, error);}
}async function getTitles() {const proxyList = await getProxyList();for (let i = 0; i < 10; i++) {await getTitlesByPage(i, proxyList);}
}getTitles();

爬取效果

效果还可以

这篇关于nodeJS搭建免费代理IP池爬取贴吧图片实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/552167

相关文章

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W