golang高效网页爬取与结构化数据处理插件库dataflowkit的使用

Golang高效网页爬取与结构化数据处理插件库Dataflowkit的使用

Dataflowkit简介

Dataflowkit(简称DFK)是一个专为Golang开发者设计的网页抓取框架,它能够根据指定的CSS选择器从网页中提取数据。

Dataflowkit Logo

网页抓取流程

网页抓取流程包含3个主要组件:

  1. 下载HTML网页(Fetch Service)
  2. 解析HTML页面并提取我们感兴趣的数据(Parse Service)
  3. 将解析后的数据编码为CSV、MS Excel、JSON、JSON Lines或XML格式

Fetch服务

fetch.d服务器用于下载HTML网页内容。根据Fetcher类型的不同,网页内容可以通过Base Fetcher或Chrome fetcher下载。

  • Base fetcher使用标准的Golang http客户端来获取页面,速度比Chrome fetcher快,但不能渲染动态JavaScript驱动的网页
  • Chrome fetcher用于渲染基于JavaScript的动态内容,它向运行在无头模式下的Chrome发送请求

Parse服务

parse.d是根据配置JSON文件中列出的规则从下载的网页中提取数据的服务。提取的数据以CSV、MS Excel、JSON或XML格式返回。

Dataflowkit的优势

  • 抓取JavaScript生成的页面
  • 从分页网站提取数据
  • 处理无限滚动页面
  • 抓取需要登录表单的网站
  • 处理Cookie和会话
  • 跟踪链接和处理详细页面
  • 管理每个域之间的请求延迟
  • 遵循robots.txt指令
  • 将中间数据保存在Diskv或Mongodb中
  • 将结果编码为CSV、MS Excel、JSON(Lines)、XML格式
  • 速度快:抓取和解析50个页面大约需要4-6秒
  • 适合处理大量数据:测试显示解析约400万个页面大约需要7小时

安装

go get -u github.com/slotix/dataflowkit

使用方法

Docker方式

  1. 安装Docker和Docker Compose
  2. 启动服务
cd $GOPATH/src/github.com/slotix/dataflowkit && docker-compose up
  1. 在第二个终端窗口中通过向解析守护进程发送POST请求来启动解析。测试用的JSON配置文件在/examples文件夹中。
curl -XPOST 127.0.0.1:8001/parse --data-binary "@$GOPATH/src/github.com/slotix/dataflowkit/examples/books.toscrape.com.json"

以下是示例JSON配置文件:

{
	"name":"collection",
	"request":{
	   "url":"https://example.com"
	},
	"fields":[
	   {
		  "name":"Title",
		  "selector":".product-container a",
		  "extractor":{
			 "types":["text", "href"],
			 "filters":[
				"trim",
				"lowerCase"
			 ],
			 "params":{
				"includeIfEmpty":false
			 }
		  }
	   },
	   {
		  "name":"Image",
		  "selector":"#product-container img",
		  "extractor":{
			 "types":["alt","src","width","height"],
			 "filters":[
				"trim",
				"upperCase"
			 ]
		  }
	   },
	   {
		  "name":"Buyinfo",
		  "selector":".buy-info",
		  "extractor":{
			 "types":["text"],
			 "params":{
				"includeIfEmpty":false
			 }
		  }
	   }
	],
	"paginator":{
	   "selector":".next",
	   "attr":"href",
	   "maxPages":3
	},
	"format":"json",
	"fetcherType":"chrome",
	"paginateResults":false
}
  1. 要停止服务,只需按Ctrl+C并运行
cd $GOPATH/src/github.com/slotix/dataflowkit && docker-compose down --remove-orphans --volumes

手动方式

  1. 启动Chrome docker容器
docker run --init -it --rm -d --name chrome --shm-size=1024m -p=127.0.0.1:9222:9222 --cap-add=SYS_ADMIN \
  yukinying/chrome-headless-browser
  1. 构建并运行fetch.d服务
cd $GOPATH/src/github.com/slotix/dataflowkit/cmd/fetch.d && go build && ./fetch.d
  1. 在新的终端窗口中构建并运行parse.d服务
cd $GOPATH/src/github.com/slotix/dataflowkit/cmd/parse.d && go build && ./parse.d
  1. 启动解析(参见上一节的步骤3)

运行测试

  • docker-compose -f test-docker-compose.yml up -d
  • ./test.sh
  • 要停止服务,只需运行docker-compose -f test-docker-compose.yml down

前端

尝试使用Dataflow kit服务的点选界面前端。它会生成JSON配置文件并向DFK解析器发送POST请求。

许可证

这是自由软件,根据BSD 3-Clause许可证发布。

贡献

欢迎您为我们的项目做出贡献。

Dataflowkit Spider


更多关于golang高效网页爬取与结构化数据处理插件库dataflowkit的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang高效网页爬取与结构化数据处理插件库dataflowkit的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Dataflowkit进行高效网页爬取与结构化数据处理

Dataflowkit是一个强大的Go语言库,专门用于网页爬取和结构化数据处理。它提供了简单易用的API,能够高效地抓取网页内容并提取结构化数据。

Dataflowkit核心功能

  1. 网页抓取:支持HTTP/HTTPS请求,处理JavaScript渲染页面
  2. 数据提取:使用CSS选择器或XPath提取结构化数据
  3. 并发处理:内置高效的并发机制
  4. 数据导出:支持JSON、CSV等多种格式

安装Dataflowkit

go get -u github.com/slotix/dataflowkit

基本使用示例

1. 简单网页抓取

package main

import (
	"fmt"
	"github.com/slotix/dataflowkit/scrape"
)

func main() {
	// 创建抓取配置
	config := scrape.Config{
		URL: "https://example.com",
		Fields: []scrape.Field{
			{
				Name: "title",
				Selector: "title",
				Extract: scrape.Extract{Type: "text"},
			},
		},
	}

	// 执行抓取
	result, err := scrape.Scrape(config)
	if err != nil {
		fmt.Printf("Error scraping page: %v\n", err)
		return
	}

	fmt.Printf("Page title: %s\n", result["title"])
}

2. 处理JavaScript渲染的页面

package main

import (
	"fmt"
	"github.com/slotix/dataflowkit/scrape"
	"time"
)

func main() {
	config := scrape.Config{
		URL: "https://dynamic-website.com",
		Fields: []scrape.Field{
			{
				Name: "dynamic_content",
				Selector: "#dynamic-element",
				Extract: scrape.Extract{Type: "text"},
			},
		},
		RenderJS: true,  // 启用JavaScript渲染
		Timeout: 10 * time.Second, // 设置超时
	}

	result, err := scrape.Scrape(config)
	if err != nil {
		fmt.Printf("Error scraping page: %v\n", err)
		return
	}

	fmt.Printf("Dynamic content: %s\n", result["dynamic_content"])
}

3. 并发抓取多个页面

package main

import (
	"fmt"
	"github.com/slotix/dataflowkit/scrape"
	"sync"
)

func scrapePage(url string, wg *sync.WaitGroup) {
	defer wg.Done()

	config := scrape.Config{
		URL: url,
		Fields: []scrape.Field{
			{
				Name: "title",
				Selector: "title",
				Extract: scrape.Extract{Type: "text"},
			},
		},
	}

	result, err := scrape.Scrape(config)
	if err != nil {
		fmt.Printf("Error scraping %s: %v\n", url, err)
		return
	}

	fmt.Printf("%s - Title: %s\n", url, result["title"])
}

func main() {
	urls := []string{
		"https://example.com",
		"https://example.org",
		"https://example.net",
	}

	var wg sync.WaitGroup

	for _, url := range urls {
		wg.Add(1)
		go scrapePage(url, &wg)
	}

	wg.Wait()
	fmt.Println("All pages scraped!")
}

高级功能

1. 分页抓取

package main

import (
	"fmt"
	"github.com/slotix/dataflowkit/scrape"
	"strconv"
)

func main() {
	baseURL := "https://example.com/products?page="
	
	for i := 1; i <= 5; i++ {
		url := baseURL + strconv.Itoa(i)
		
		config := scrape.Config{
			URL: url,
			Fields: []scrape.Field{
				{
					Name: "products",
					Selector: ".product",
					Extract: scrape.Extract{
						Type: "text",
						All:  true, // 获取所有匹配元素
					},
				},
			},
		}

		result, err := scrape.Scrape(config)
		if err != nil {
			fmt.Printf("Error scraping page %d: %v\n", i, err)
			continue
		}

		products := result["products"].([]interface{})
		fmt.Printf("Page %d - Found %d products\n", i, len(products))
	}
}

2. 数据导出为JSON

package main

import (
	"encoding/json"
	"fmt"
	"github.com/slotix/dataflowkit/scrape"
	"os"
)

func main() {
	config := scrape.Config{
		URL: "https://example.com/products",
		Fields: []scrape.Field{
			{
				Name: "name",
				Selector: ".product-name",
				Extract: scrape.Extract{Type: "text"},
			},
			{
				Name: "price",
				Selector: ".product-price",
				Extract: scrape.Extract{Type: "text"},
			},
		},
		Paginator: scrape.Paginator{
			Selector: ".next-page",
			Attr:     "href",
			MaxPages: 3,
		},
	}

	results, err := scrape.ScrapeAll(config)
	if err != nil {
		fmt.Printf("Error scraping: %v\n", err)
		return
	}

	// 转换为JSON
	jsonData, err := json.MarshalIndent(results, "", "  ")
	if err != nil {
		fmt.Printf("Error marshaling JSON: %v\n", err)
		return
	}

	// 写入文件
	err = os.WriteFile("products.json", jsonData, 0644)
	if err != nil {
		fmt.Printf("Error writing file: %v\n", err)
		return
	}

	fmt.Println("Data successfully exported to products.json")
}

性能优化技巧

  1. 合理设置并发数:通过scrape.SetConcurrency(n)控制并发请求数量
  2. 使用缓存:配置scrape.WithCache()减少重复请求
  3. 设置合理的超时:避免长时间等待无响应的页面
  4. 限制抓取范围:使用scrape.WithAllowedDomains()限制抓取的域名

注意事项

  1. 遵守目标网站的robots.txt规则
  2. 设置合理的请求间隔,避免被封禁
  3. 处理可能遇到的反爬机制
  4. 考虑使用代理IP池应对IP限制

Dataflowkit提供了强大而灵活的工具集,可以满足从简单到复杂的各种网页抓取需求。通过合理配置和优化,可以构建高效的网络爬虫系统。

回到顶部