golang高效网页爬取与结构化数据处理插件库dataflowkit的使用
Golang高效网页爬取与结构化数据处理插件库Dataflowkit的使用
Dataflowkit简介
Dataflowkit(简称DFK)是一个专为Golang开发者设计的网页抓取框架,它能够根据指定的CSS选择器从网页中提取数据。
网页抓取流程
网页抓取流程包含3个主要组件:
- 下载HTML网页(Fetch Service)
- 解析HTML页面并提取我们感兴趣的数据(Parse Service)
- 将解析后的数据编码为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方式
- 安装Docker和Docker Compose
- 启动服务
cd $GOPATH/src/github.com/slotix/dataflowkit && docker-compose up
- 在第二个终端窗口中通过向解析守护进程发送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
}
- 要停止服务,只需按Ctrl+C并运行
cd $GOPATH/src/github.com/slotix/dataflowkit && docker-compose down --remove-orphans --volumes
手动方式
- 启动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
- 构建并运行fetch.d服务
cd $GOPATH/src/github.com/slotix/dataflowkit/cmd/fetch.d && go build && ./fetch.d
- 在新的终端窗口中构建并运行parse.d服务
cd $GOPATH/src/github.com/slotix/dataflowkit/cmd/parse.d && go build && ./parse.d
- 启动解析(参见上一节的步骤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许可证发布。
贡献
欢迎您为我们的项目做出贡献。
更多关于golang高效网页爬取与结构化数据处理插件库dataflowkit的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang高效网页爬取与结构化数据处理插件库dataflowkit的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Dataflowkit进行高效网页爬取与结构化数据处理
Dataflowkit是一个强大的Go语言库,专门用于网页爬取和结构化数据处理。它提供了简单易用的API,能够高效地抓取网页内容并提取结构化数据。
Dataflowkit核心功能
- 网页抓取:支持HTTP/HTTPS请求,处理JavaScript渲染页面
- 数据提取:使用CSS选择器或XPath提取结构化数据
- 并发处理:内置高效的并发机制
- 数据导出:支持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")
}
性能优化技巧
- 合理设置并发数:通过
scrape.SetConcurrency(n)
控制并发请求数量 - 使用缓存:配置
scrape.WithCache()
减少重复请求 - 设置合理的超时:避免长时间等待无响应的页面
- 限制抓取范围:使用
scrape.WithAllowedDomains()
限制抓取的域名
注意事项
- 遵守目标网站的robots.txt规则
- 设置合理的请求间隔,避免被封禁
- 处理可能遇到的反爬机制
- 考虑使用代理IP池应对IP限制
Dataflowkit提供了强大而灵活的工具集,可以满足从简单到复杂的各种网页抓取需求。通过合理配置和优化,可以构建高效的网络爬虫系统。