首页 > 其他分享 >【Go】基于 Go 1.19 的站点模板爬虫【实战演练版】

【Go】基于 Go 1.19 的站点模板爬虫【实战演练版】

时间:2024-07-27 19:26:28浏览次数:13  
标签:err movie 爬虫 1.19 go Go colly

0. 前言

Go 语言,也被称为Golang,是由Google开发的一种开源编程语言,它在 2009 年首次发布,并在 2012 年正式开源。Go 语言被设计用来简化大型软件的开发,特别注重并发编程和内存安全。

0.1 特点

  1. 静态类型:Go 是静态类型语言,这意味着类型在编译时已经确定,有助于在编译阶段捕捉错误。
  2. 编译型语言:Go 语言编写的程序会被编译成机器码,直接运行在硬件上,因此执行效率较高。
  3. 并发编程:Go 内置了goroutine(轻量级线程)和channel(用于goroutine之间通信的管道),使得并发编程变得简单。
  4. 内存安全:Go 语言通过垃圾回收(GC)机制来自动管理内存,减少了内存泄露的风险。
  5. 简洁的语法:Go 语言的语法简洁明了,易于学习和理解。
  6. 工具链:Go 语言拥有一套完整的工具链,包括但不限于格式化工具gofmt、包管理工具go get等。
  7. 跨平台:Go 语言支持跨平台编译,可以轻松地编译为不同操作系统和架构的二进制文件。

0.2 优势

  1. 高效的并发处理:通过 goroutine 和 channel,Go 语言使得并发编程变得简单而高效。
  2. 快速编译:Go 语言的编译速度非常快,这使得开发周期缩短,提高了开发效率。
  3. 易于维护:Go 语言的代码结构清晰,易于维护和重构。
  4. 强大的标准库:Go 语言提供了丰富的标准库,覆盖网络、I/O、数据处理等多种功能。
  5. 内存安全:通过垃圾回收机制,减少了内存泄露和指针错误的风险。
  6. 跨平台:可以很容易地为不同的操作系统和架构编译 Go 程序。

0.3 缺点

  1. 垃圾回收:虽然垃圾回收机制减少了内存管理的负担,但有时候 GC 的不可预测性可能会影响性能。
  2. 错误处理:Go语言的错误处理机制(通过返回错误值)与传统try-catch不同,有时会导致代码中错误处理逻辑过于冗长。
  3. 包管理:虽然 Go 的包管理工具在不断改进,但在早期版本中,模块化的支持并不完善。
  4. 泛型支持:直到 Go 1.18 版本才引入了泛型,之前版本的 Go 语言缺少泛型支持,这在某些场景下限制了代码的复用。
  5. 社区和生态系统:虽然 Go 社区活跃,但与一些老牌编程语言相比,其生态系统和第三方库可能还不够丰富。官方社区
  6. 类型系统:Go 的类型系统相对简单,对于某些复杂的编程场景可能不够灵活。

总的来说,Go 语言因其简洁、高效和易于并发编程的特点,在云计算、微服务、网络编程等领域得到了广泛的应用。尽管它有一些缺点,但这些通常不会影响它在特定领域的优势和适用性。

基于 Go 1.19 的站点模板爬虫就是一种使用 Go 语言编写的程序,专门用于从互联网上抓取网页内容。站点模板爬虫通常利用Go 语言的高并发特性来提高爬取效率。下面将简要介绍如何构建一个基于 Go 1.19 的站点模板爬虫。

1. 准备工作

确保你的开发环境已经安装了 Go 1.19 或更高版本的 SDK,并且配置好了 GOPATH 等环境变量。
要验证是否已经安装了 Go 1.19 或更高版本的 SDK,并且配置好了 GOPATH 等环境变量,可以通过以下步骤进行:

1.1 检查Go版本

打开终端(在 Windows 上是命令提示符或 PowerShell ),运行以下命令来检查安装的 Go 版本:

go version

这个命令将输出当前安装的 Go 版本。如果输出的版本是1.19或更高,说明你的 Go SDK 安装正确。

1.2 检查环境变量

要检查是否正确设置了GOPATH和其他相关环境变量,可以运行以下命令:
在Linux或macOS上:

echo $GOPATH
echo $GOROOT

在 Windows 上(命令提示符):

echo %GOPATH%
echo %GOROOT%

或者,如果你使用的是PowerShell

$env:GOPATH
$env:GOROOT

这些命令将显示GOPATHGOROOT环境变量的值。如果它们被正确设置,那么你应该能看到它们的路径。

1.3 验证Go工作区

除了检查环境变量,你还可以通过以下命令来验证 Go 工作区是否配置正确:

go env

这个命令将列出所有与 Go 相关的环境变量。检查以下关键变量:

  • GOPATH: 你的 Go 工作区的路径。
  • GOROOT: Go SDK 的安装路径。
  • GOBIN: 存储编译后二进制文件的路径(通常位于$GOPATH/bin)。
    确保这些路径正确无误。

1.4 示例输出

以下是一个示例输出,显示了一个正确配置的 Go 环境:

$ go version
go version go1.19 darwin/amd64
$ echo $GOPATH
/Users/yourusername/go
$ echo $GOROOT
/usr/local/go
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN="/Users/yourusername/go/bin"
GOCACHE="/Users/yourusername/Library/Caches/go-build"
GOENV="/Users/yourusername/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/yourusername/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/yourusername/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.19"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8_/8b4g0v2d2w9g1x8bgj0zyn4c0000gn/T/go-build3570152476=/tmp/go-build -gno-record-gcc-switches -fno-common"

如果以上步骤都没有问题,那么你的Go SDK和相关的环境变量应该已经配置好了。如果有任何问题,你可能需要重新安装 Go 或重新配置环境变量。

2. 选择库

在Go语言中,有几个流行的库可以用来编写爬虫,如:

  • net/http: 用于发起网络请求。
  • golang.org/x/net/html: 用于解析HTML
  • colly: 一个高性能的爬虫框架。

3. 爬虫基本结构

以下是构建站点模板爬虫的基本步骤:

3.1 发起网络请求

使用net/http包来发起GET请求,获取网页内容。

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
)
func fetch(url string) ([]byte, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    return ioutil.ReadAll(resp.Body)
}

3.2 解析HTML

使用golang.org/x/net/html包解析HTML文档,提取需要的数据。

func parse(html []byte) {
    doc, err := html.Parse(bytes.NewReader(html))
    if err != nil {
        panic(err)
    }
    // 遍历DOM,提取数据
}

3.3 使用爬虫框架(可选)

如果不想手动处理太多细节,可以使用colly这样的框架。

package main
import (
    "fmt"
    "github.com/gocolly/colly"
)
func main() {
    c := colly.NewCollector()
    c.OnHTML("div.some-class", func(e *colly.HTMLElement) {
        fmt.Println(e.Text)
    })
    c.Visit("http://example.com")
}

4. 实现站点模板

站点模板指的是你希望爬虫遵循的页面结构。你需要定义好如何从页面中提取有用信息,比如:

  • 标题
  • 内容
  • 链接
  • 图片等资源

5. 遵循 robots.txt 规则

在爬取网站之前,应当检查网站的robots.txt文件,确保你的爬虫行为符合网站管理员的规则。

6. 防止被封禁

  • 设置合理的请求间隔。
  • 使用随机的User-Agent
  • 可能的话,使用代理IP

7. 错误处理和日志记录

合理处理可能出现的错误,并记录日志,这对于调试和监控爬虫的状态非常重要。

8. 并发控制

利用 Go 的goroutinechannel实现并发控制,提高爬取效率。

9. 示例代码

以下是一个简单的示例,展示如何使用 Go 语言和colly框架编写一个基本的爬虫:

package main
import (
    "fmt"
    "github.com/gocolly/colly"
)
func main() {
    c := colly.NewCollector()
    // On every a element which has href attribute call callback
    c.OnHTML("a[href]", func(e *colly.HTMLElement) {
        link := e.Attr("href")
        // Visit link found on page
        c.Visit(e.Request.AbsoluteURL(link))
    })
    // Before making a request print "Visiting ..."
    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })
    // Start scraping on https://example.com
    c.Visit("https://example.com")
}

10. 实战演练

注意: 构建爬虫时,应始终遵守相关法律法规,尊重网站所有者的权益,不要进行过度的请求压力,以避免对网站造成不利影响。

以下是一个使用 Go 1.19 编写的简单示例程序,用于爬取豆瓣 Top 250 电影的名称、评分、评论人数、影评和发表年份,并将这些信息保存到CSV文件中。由于直接爬取网页内容可能违反服务条款,请在遵守相关法律法规和服务条款的前提下使用此代码。

首先,请确保安装了以下Go包:

  • github.com/gocolly/colly:用于网页爬取。
  • github.com/tealeg/xlsx:用于生成Excel文件。

使用以下命令安装所需的包:

go get -u github.com/gocolly/colly
go get -u github.com/tealeg/xlsx

CSV 版:

package main
import (
        "encoding/csv"
        "fmt"
        "os"
        "strconv"
        "strings"
        "github.com/gocolly/colly"
)
type Movie struct {
        Title       string
        Rating      string
        ReviewCount string
        Review      string
        Year        string
}
func main() {
        // 创建CSV文件
        file, err := os.Create("Top_250.csv")
        if err != nil {
                fmt.Println("Cannot create file", err)
                return
        }
        defer file.Close()
        writer := csv.NewWriter(file)
        defer writer.Flush()
        // 写入标题行
        writer.Write([]string{"电影名称", "评分", "评论人数", "影评", "发表年份"})
        // 初始化爬虫
        c := colly.NewCollector(
                colly.AllowedDomains("movie.douban.com"),
        )
        // 解析电影信息
        c.OnHTML("div.item", func(e *colly.HTMLElement) {
                var movie Movie
                movie.Title = e.ChildText("span.title")
                movie.Rating = e.ChildText("span.rating_num")
                movie.ReviewCount = strings.Trim(e.ChildText("div.star span"), "人评价")
                movie.Review = e.ChildText("spaninq")
                movie.Year = e.ChildText("div.bd p")
                // 清洗年份信息
                if idx := strings.Index(movie.Year, "上映时间:"); idx != -1 {
                        year := strings.Fields(movie.Year[idx:])
                        if len(year) > 0 {
                                movie.Year = year[1]
                        }
                }
                // 写入数据到CSV
                writer.Write([]string{
                        movie.Title,
                        movie.Rating,
                        movie.ReviewCount,
                        movie.Review,
                        movie.Year,
                })
        })
        // 爬取豆瓣Top 250电影
        for i := 0; i < 10; i++ {
                url := fmt.Sprintf("https://movie.douban.com/top250?start=%d", i*25)
                err := c.Visit(url)
                if err != nil {
                        fmt.Println("Visit error:", err)
                        return
                }
        }
        fmt.Println("爬取完成")
}

Excel 版:

package main

import (
	"fmt"
	"github.com/tealeg/xlsx"
	"github.com/gocolly/colly"
)

type Movie struct {
	Title       string
	Rating      string
	ReviewCount string
	Review      string
	Year        string
}

func main() {
	// 创建一个新的Excel文件
	file := xlsx.NewFile()
	sheet, err := file.AddSheet("Top 250")
	if err != nil {
		fmt.Printf("Error adding sheet: %s\n", err)
		return
	}

	// 创建标题行
	titleRow := sheet.AddRow()
	titleRow.SetHeightCM(1) // 设置行高
	titleRow.AddCell().Value = "电影名称"
	titleRow.AddCell().Value = "评分"
	titleRow.AddCell().Value = "评论人数"
	titleRow.AddCell().Value = "影评"
	titleRow.AddCell().Value = "发表年份"

	// 初始化爬虫
	c := colly.NewCollector(
		colly.AllowedDomains("movie.douban.com"),
	)

	// 解析电影信息
	c.OnHTML("div.item", func(e *colly.HTMLElement) {
		var movie Movie
		movie.Title = e.ChildText("span.title")
		movie.Rating = e.ChildText("span.rating_num")
		movie.ReviewCount = strings.Trim(e.ChildText("div.star span"), "人评价")
		movie.Review = e.ChildText("span.inq")
		movie.Year = e.ChildText("div.bd p")

		// 清洗年份信息
		if idx := strings.Index(movie.Year, "上映时间:"); idx != -1 {
			year := strings.Fields(movie.Year[idx:])
			if len(year) > 1 {
				movie.Year = year[1]
			}
		}

		// 写入数据到Excel
		row := sheet.AddRow()
		row.AddCell().Value = movie.Title
		row.AddCell().Value = movie.Rating
		row.AddCell().Value = movie.ReviewCount
		row.AddCell().Value = movie.Review
		row.AddCell().Value = movie.Year
	})

	// 爬取豆瓣Top 250电影
	for i := 0; i < 10; i++ {
		url := fmt.Sprintf("https://movie.douban.com/top250?start=%d", i*25)
		err := c.Visit(url)
		if err != nil {
			fmt.Println("Visit error:", err)
			return
		}
	}

	// 保存Excel文件
	err = file.Save("Top_250.xls")
	if err != nil {
		fmt.Printf("Error saving file: %s\n", err)
		return
	}

	fmt.Println("Excel file created successfully.")
}

在此代码中,我们首先创建了一个xlsx.File对象,并添加了一个名为 “Top 250” 的工作表。然后,我们添加了一个标题行,并遍历电影数据,将每部电影的信息添加到工作表中。最后,我们保存了 Excel 文件。

此程序执行以下步骤:

  1. 初始化一个Excel文件并添加一个工作表。
  2. 定义一个Movie结构体来存储电影信息。
  3. 使用colly包创建一个爬虫,并设置爬取规则。
  4. 遍历豆瓣Top 250电影的每一页,提取电影信息。
  5. 将提取的信息写入Excel工作表的每一行。
  6. 保存Excel文件。

此外,为了防止对豆瓣服务器造成过大压力,程序中设置了每次爬取 25 部电影,共爬取 10 页(250部电影)。根据需要,可以自行调节这些参数。

标签:err,movie,爬虫,1.19,go,Go,colly
From: https://blog.csdn.net/Young_Pro/article/details/140735914

相关文章

  • 入门C语言Day18——break&continue&goto语句
    前面的博文中有提到do-while与for循环语句,其中的流程图中有break和continue这两个部分还没解释。所以今天先来解释一下break与continue语句。break和continue两个关键字都被运用在循环中。break的作用是永久的终止循环,只要break被执行,直接就会跳出循环,继续往后执行。......
  • Golang 高性能 Websocket 库 gws 使用与设计(一)
    前言大家好这里是,白泽,这期分析一下golang开源高性能websocket库gws。视频讲解请关注......
  • Python毕业设计基于Django的网上购物销售系统(代码+数据库+文档LW+运行成功)
    文末获取资源,收藏关注不迷路文章目录一、项目介绍二、主要使用技术三、研究内容四、核心代码五、文章目录一、项目介绍随着互联网技术的不断发展和普及,电子商务行业迅速崛起。越来越多的消费者选择在线购物,享受便捷、快速的购物体验。因此,开发一款基于Python的购物......
  • python毕业设计基于Django的电子书阅读系统的设计与实现 爬虫+大屏可视化
    文末获取资源,收藏关注不迷路文章目录一、项目介绍二、主要使用技术三、研究内容+四、核心代码五、文章目录一、项目介绍随着互联网的普及和移动设备的广泛应用,人们获取信息和阅读的方式发生了巨大变化。传统的纸质书籍阅读方式虽然经典,但存在携带不便、更新速度慢等......
  • Pyhton毕业设计基于django的旅游管理系统景点酒店订票和特产购物
    文末获取资源,收藏关注不迷路文章目录一、项目介绍亮点:景点和酒店订票,特色购物商城,在线地图功能二、主要使用技术三、研究内容四、核心代码五、文章目录一、项目介绍随着经济的快速发展和人民生活水平的提高,旅游业在全球范围内迅速发展,成为推动经济增长的重要力量。......
  • Django 仅发送更改响应而不是完整模板
    如何只发送一条警报消息来响应请求,而不必发送专门为警报制作的模板?我正在使用Javascript异步调用。我只需要警报html响应即可呈现InnerHTML查看@login_required(login_url="/login/")@csrf_protectdefusersave(request):msg=messages.add_message(req......
  • 如何修复 Google Colab 中未安装 Drive 和未正确设置路径的问题?
    我是Python新手,没有GoogleColab高级技术的经验。我一直在尝试编写一个Python代码,我想从我的GoogleDrive读取文本文件或MATLAB变量。然后我会对这些数据进行分析。我按照这个LINK的答案来安装我的驱动器。我在下面提供我的代码和屏幕截图来详细说明。我想要......
  • 计算机毕业设计ssm/springoot商场停车场服务系统
    通过对商场用户停车服务管理的调查研究,要求系统具有以下功能: 1.全面展示停车场的服务功能及环境。  2.存储用户信息。 3.车位信息用户进行入场停车功能。4.入场停车用户进行出场缴费功能,管理员进行审核。5.停车记录用户进行支付功能,管理员进行审核。  6.提供管......
  • 计算机毕业设计ssm/springoot网上购物商城系统kgyax源码lw包调试
    框架:ssm/springoot都有jdk版本:1.8及以上ide工具:IDEA或者eclipse数据库:mysql 编程语言:java前端:layui+bootstrap+jsp详细技术:HTML+CSS+JS+jsp+springmvc+mybatis+MYSQL+MAVEN+tomcat开发工具IntelliJIDEA:一先进的IDE,用于java开发,提供了丰富的工具和功能。开......
  • 【Django】 js实现动态赋值、显示show隐藏hide效果
    文章目录需要达到的前端效果预览:实现步骤复制bootstrp代码(buttons)复制bootstrp代码(Alert警告框)写js测试效果需要达到的前端效果预览:{%loadstatic%}<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="......