Go语言多线程爬虫万能模板它来了!

对于长期从事爬虫行业的技术员来说,通过技术手段实现抓取海量数据并且做到可视化处理,我在想如果能写一个万能的爬虫模板,后期遇到类似的工作只要套用模板就能解决大部分的问题,如此提高工作效率何乐而不为?

在这里插入图片描述

以下是一个基本的 Go 爬虫程序的示例,用于爬取网站并做可视化处理。这个爬虫使用了多线程来提高效率,并使用了代理信息来避免被网站反爬虫机制封锁。

package main

import (
	"fmt"
	"net/http"
	"os"
	"strings"
	"sync"
)

const (
	proxyHost = "www.duoip.cn"
	proxyPort = 8000
)

func main() {
	// 创建一个字典来存储商品信息
	productMap := make(map[string]string)

	// 创建一个锁来保护商品字典:= sync.Mutex{}

	// 创建一个队列来存储要爬取的页面
	queue := make(chan string)

	// 创建一个信号量来控制并发数量
	sem := make(chan int, 10)

	// 创建一个信号量来控制线程数量
	threads := make(chan int, 10)

	// 创建一个信号量来控制线程数量
	complete := make(chan bool)

	// 启动一个线程来处理队列
	go handleQueue(queue, sem, productMap, lock, complete)

	// 启动10个线程来爬取页面
	for i := 0; i < 10; i++ {
		threads <- i
	}

	// 关闭信号量来停止线程
	close(threads)

	// 关闭信号量来停止线程
	close(sem)

	// 关闭信号量来停止爬取
	close(queue)

	// 等待所有线程完成
	for i := 0; i < 10; i++ {
		<-complete
	}

	// 打印商品信息
	for _, product := range productMap {
		fmt.Println(product)
	}
}

func handleQueue(queue chan string, sem chan int, productMap map[string]string, lock sync.Mutex, complete chan bool) {
	// 获取信号量来控制并发数量
	sem <- 1
	defer func() {
		<-sem
	}()

	// 从队列中取出一个页面
	page := <-queue

	// 使用代理信息进行网络请求
	resp, err := http.Get(fmt.Sprintf("http://%s:%d/%s", proxyHost, proxyPort, page))
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	// 检查响应是否成功
	if resp.StatusCode != http.StatusOK {
		fmt.Println("Error:", resp.Status)
		return
	}

	// 解析响应体中的商品信息
	var product string
	if err := http.StripPrefix("/product/", resp.Body, &product); err != nil {
		fmt.Println(err)
		return
	}

	// 使用锁保护商品字典.Lock()
	defer.Unlock()

	// 将商品信息添加到字典中
	productMap[product] = ""

	// 将信号量发送给下一个线程
	sem <- 1
}

func parsePage(page string) {
	// 使用正则表达式解析页面中的商品信息
	// 这里只是一个示例,实际的解析逻辑可能会更复杂
	var product, price string
	if match := strings.MustCompile(`商品名称: (\w+), 价格: (\d+)`).FindStringSubmatch(page); match != nil {
		product = match[1]
		price = match[2]
	}
}

这个程序首先创建了一个商品字典和一个锁来保护字典。然后,它创建了一个队列和一个信号量来控制并发数量和线程数量。接下来,它启动了一个线程来处理队列,以及10个线程来爬取页面。在每个爬取线程中,它从队列中取出一个页面,使用代理信息进行网络请求,解析响应体中的商品信息,并将商品信息添加到商品字典中。

在每个爬取线程完成后,它将信号量发送给下一个线程,以控制并发数量。最后,程序打印出所有爬取到的商品信息。需要注意的是,这只是一个基本的示例,实际的爬虫程序可能会更复杂,需要处理更多的异常情况和错误。

上面的详细程序步骤,是多线程并且可视化处理的爬虫通用模板。利用模版可以解决效率问题,爬虫IP的辅助可以让数据爬取更快捷。如果爬虫代码问题以及爬虫ip问题都可以一起讨论讨论。


http://www.niftyadmin.cn/n/5206060.html

相关文章

八股文面试day5

测试即&#xff08;验证产品特性是否符合用户需求、检测系统是否能满足客户需求&#xff0c;是否能正常运行&#xff0c;数据会有没有正确&#xff09; 测试流程就是&#xff1a;需求评审&#xff0c;编写测试计划&#xff0c;设计测试用例&#xff0c;执行测试用例&#xff0…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现城市多级联动Demo(上)

目录 概述 云数据库开发 一、创建云数据库的对象类型。 二、预置数据&#xff08;为对象类型添加数据条目&#xff09;。 三、部署云数据库 云函数实现业务逻辑 一、创建云函数 二、云函数目录讲解 三、创建resources目录 四、获取云端凭据 五、导出之前创建的元数据…

C/C++杂谈-printf的可变参数机制

C/C杂谈-printf的可变参数机制 文章目录 C/C杂谈-printf的可变参数机制printf的使用printf的源码源码剖析 多参数实现机制原理 C11引入了可变参数模板机制&#xff0c;对模板参数进行了高度泛化&#xff0c;但是对于可变参数其实C语言学习中早已遇到过&#xff0c;那就是printf…

LORA 教程

1 什么是LoRa 2 LoRa调制解调技术 3 什么是loraWAN 4 LoRa和LoRaWAN详细介绍 5 LoRaWAN 物理层&#xff08;PHY&#xff09;详解 6 LoRaWAN MAC帧格式详解 7 LoraWAN MAC控制命令详解 8 LoRaWAN 设备入网流程详解&#xff08;OTAA和ABP&#xff09; 9 LoRaWAN 自适…

WCF Demo

1.WCF概述 WCF是用于构建分布式应用程序和服务的框架。它提供了用于创建和管理分布式系统的工具和库&#xff0c;支持多种通信协议和传输方式&#xff0c;如HTTP、TCP、Named Pipes等。WCF基于服务的概念&#xff0c;允许开发人员定义服务契约、实现服务逻辑&#xff0c;并通过…

【代数学习题4.2】从零理解范数与迹 —— 求数域元素的范数与迹

从零理解范数与迹 —— 求数域元素的范数与迹 写在最前面题目解答 2. 范数 N N N思路求解过程python求解 3. 数域 K K K 的范数 N K N_K NK​思路求解过程Python求解分析解题步骤 4. 迹 T T T求解过程共轭元素计算迹 python求解分析解题步骤 5. 数域 K K K 的迹 T K T_K …

Navicat 技术指引 | 适用于 GaussDB 的模型功能

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对 GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

java.sql.SQLException: Connection has already been closed

背景&#xff1a; 通过一个接口触发后台数据库的批量更新操作&#xff0c;原本只是一个触发动作&#xff0c;不需要返回值&#xff0c;因此没有关心出现的http超时问题。后面发现批量更新任务中断了&#xff0c;查日志发现了Connection has already been closed报错。 具体的…