golang命令行网页爬虫与数据抓取插件库crawley的使用
Golang命令行网页爬虫与数据抓取插件库crawley的使用
特性
- 快速HTML SAX解析器(基于x/net/html)
- JavaScript/CSS词法解析器(基于tdewolff/parse) - 从JS代码和
url()
属性中提取API端点 - 代码简洁(少于1500行),100%测试覆盖率
- 抓取大多数有用的资源URL(图片、视频、音频、表单等)
- 发现的URL会输出到stdout并保证唯一性(忽略片段)
- 可配置扫描深度(默认0,限制在起始主机和路径)
- 支持robots.txt规则和站点地图
brute
模式 - 扫描HTML评论中的URL(可能导致虚假结果)- 支持HTTP_PROXY/HTTPS_PROXY环境变量和代理认证
- 仅目录扫描模式(快速扫描)
- 用户自定义cookie(支持curl格式)
- 用户自定义headers(支持curl格式)
- 标签过滤器 - 指定要抓取的标签
- URL忽略 - 忽略包含特定子串的URL
- 子域名支持
安装
- 下载预编译二进制文件(适用于Linux、FreeBSD、macOS和Windows)
- Archlinux用户可以使用AUR助手安装:
paru -S crawley-bin
使用示例
# 打印第一页的所有链接:
crawley http://some-test.site
# 打印所有JS文件和API端点:
crawley -depth -1 -tag script -js http://some-test.site
# 打印JS中的所有端点:
crawley -js http://some-test.site/app.js
# 下载网站所有png图片:
crawley -depth -1 -tag img http://some-test.site | grep '\.png$' | wget -i -
# 快速目录遍历:
crawley -headless -delay 0 -depth -1 -dirs only http://some-test.site
完整命令行选项
crawley [flags] url
可用选项(默认值):
-all
扫描所有已知来源(js/css/...)
-brute
扫描HTML注释
-cookie value
请求的额外cookie,可多次使用,支持'@'前缀文件
-css
扫描CSS中的URL
-delay duration
每个请求的延迟(0表示禁用)(默认150ms)
-depth int
扫描深度(-1表示无限制)
-dirs string
非资源URL的处理策略: show/hide/only(默认"show")
-header value
请求的额外header,可多次使用,支持'@'前缀文件
-headless
禁用预检HEAD请求
-ignore value
爬取过程中要忽略的URL模式
-js
扫描JS代码中的端点
-proxy-auth string
代理认证信息: user:password
-robots string
robots.txt处理策略: ignore/crawl/respect(默认"ignore")
-silent
禁止在stderr输出信息和错误
-skip-ssl
跳过SSL验证
-subdomains
支持子域名(如找到www.domain.com也会爬取)
-tag value
标签过滤器,单一或逗号分隔的标签名
-timeout duration
请求超时(最小1秒,最大10分钟)(默认5s)
-user-agent string
用户代理字符串
-version
显示版本
-workers int
工作线程数(默认CPU核心数)
自动补全
Crawley支持通过complete
命令在bash和zsh中实现标志自动补全:
complete -C "/full-path-to/bin/crawley" crawley
许可证
MIT License
更多关于golang命令行网页爬虫与数据抓取插件库crawley的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang命令行网页爬虫与数据抓取插件库crawley的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Crawley构建Golang命令行网页爬虫
Crawley是一个强大的Go语言网页爬虫和数据抓取库,它提供了简洁的API和丰富的功能来帮助开发者快速构建爬虫应用。下面我将介绍如何使用Crawley构建一个命令行网页爬虫。
安装Crawley
首先,我们需要安装Crawley库:
go get github.com/slyrz/crawley
基本爬虫示例
下面是一个简单的Crawley爬虫示例,它可以抓取网页上的所有链接:
package main
import (
"fmt"
"log"
"os"
"github.com/slyrz/crawley"
"github.com/slyrz/crawley/filter"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go <url>")
return
}
url := os.Args[1]
// 创建爬虫配置
config := crawley.Config{
MaxDepth: 2, // 最大爬取深度
MaxThreads: 5, // 并发线程数
UserAgent: "MyCrawler/1.0", // 用户代理
}
// 创建爬虫实例
crawler := crawley.NewCrawler(config)
// 设置URL过滤器 - 只爬取同域名的链接
domainFilter := filter.NewDomainFilter(url)
crawler.AddFilter(domainFilter)
// 设置响应处理器
crawler.OnResponse(func(resp *crawley.Response) {
fmt.Printf("Fetched: %s (Status: %d)\n", resp.URL, resp.StatusCode)
// 提取页面中的所有链接
links := resp.Links()
for _, link := range links {
fmt.Println("Found link:", link)
}
})
// 设置错误处理器
crawler.OnError(func(err error, url string) {
log.Printf("Error fetching %s: %v\n", url, err)
})
// 开始爬取
fmt.Printf("Starting crawl of %s...\n", url)
crawler.Crawl(url)
fmt.Println("Crawl completed!")
}
数据抓取功能
Crawley还提供了强大的数据抓取功能,可以使用CSS选择器或XPath来提取特定数据:
package main
import (
"fmt"
"log"
"os"
"github.com/slyrz/crawley"
"github.com/slyrz/crawley/selector"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go <url>")
return
}
url := os.Args[1]
config := crawley.Config{
MaxDepth: 1,
MaxThreads: 3,
}
crawler := crawley.NewCrawler(config)
// 设置数据提取器
crawler.OnResponse(func(resp *crawley.Response) {
// 使用CSS选择器提取标题
title, err := resp.SelectText("title")
if err != nil {
log.Printf("Error extracting title: %v", err)
} else {
fmt.Printf("Page title: %s\n", title)
}
// 提取所有段落文本
paragraphs, err := resp.SelectAllText("p")
if err != nil {
log.Printf("Error extracting paragraphs: %v", err)
} else {
fmt.Println("\nParagraphs:")
for i, p := range paragraphs {
fmt.Printf("%d: %s\n", i+1, p)
}
}
// 提取链接和对应的文本
links, err := resp.SelectAll("a", selector.Attr("href"), selector.Text())
if err != nil {
log.Printf("Error extracting links: %v", err)
} else {
fmt.Println("\nLinks:")
for _, link := range links {
fmt.Printf("%s -> %s\n", link[1], link[0])
}
}
})
fmt.Printf("Crawling %s for data...\n", url)
crawler.Crawl(url)
}
高级功能:限速与持久化
Crawley还支持限速和结果持久化等高级功能:
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"time"
"github.com/slyrz/crawley"
"github.com/slyrz/crawley/filter"
"github.com/slyrz/crawley/selector"
)
type PageData struct {
URL string `json:"url"`
Title string `json:"title"`
Links []string `json:"links"`
Images []string `json:"images"`
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go <url>")
return
}
url := os.Args[1]
config := crawley.Config{
MaxDepth: 3,
MaxThreads: 5,
RequestDelay: 1 * time.Second, // 每个请求之间的延迟
Timeout: 10 * time.Second,
}
crawler := crawley.NewCrawler(config)
crawler.AddFilter(filter.NewDomainFilter(url))
outputFile, err := os.Create("output.json")
if err != nil {
log.Fatal(err)
}
defer outputFile.Close()
encoder := json.NewEncoder(outputFile)
crawler.OnResponse(func(resp *crawley.Response) {
title, _ := resp.SelectText("title")
links, _ := resp.SelectAll("a", selector.Attr("href"))
images, _ := resp.SelectAll("img", selector.Attr("src"))
pageData := PageData{
URL: resp.URL,
Title: title,
Links: links,
Images: images,
}
// 将数据写入JSON文件
if err := encoder.Encode(pageData); err != nil {
log.Printf("Error writing to file: %v", err)
}
fmt.Printf("Processed: %s (%d links, %d images)\n",
resp.URL, len(links), len(images))
})
crawler.OnError(func(err error, url string) {
log.Printf("Error crawling %s: %v", url, err)
})
fmt.Printf("Starting advanced crawl of %s...\n", url)
crawler.Crawl(url)
fmt.Println("Crawl completed! Results saved to output.json")
}
命令行参数处理
为了使爬虫更灵活,我们可以使用Go的flag包来添加命令行参数:
package main
import (
"flag"
"fmt"
"log"
"github.com/slyrz/crawley"
"github.com/slyrz/crawley/filter"
)
func main() {
// 定义命令行参数
url := flag.String("url", "", "URL to start crawling from")
depth := flag.Int("depth", 2, "Maximum crawl depth")
threads := flag.Int("threads", 5, "Number of concurrent threads")
output := flag.String("output", "results.txt", "Output file path")
flag.Parse()
if *url == "" {
fmt.Println("Please provide a starting URL with -url")
return
}
config := crawley.Config{
MaxDepth: *depth,
MaxThreads: *threads,
}
crawler := crawley.NewCrawler(config)
crawler.AddFilter(filter.NewDomainFilter(*url))
// 这里可以添加响应处理器和错误处理器
// ...
fmt.Printf("Starting crawl of %s with depth %d and %d threads...\n",
*url, *depth, *threads)
crawler.Crawl(*url)
fmt.Printf("Results saved to %s\n", *output)
}
总结
Crawley是一个功能强大且灵活的Go语言爬虫库,通过上面的示例,我们可以看到它提供了:
- 并发控制
- 深度控制
- URL过滤
- 数据提取(CSS选择器和XPath)
- 限速功能
- 错误处理
- 可扩展的处理器接口
你可以根据实际需求组合这些功能来构建各种复杂的爬虫应用。记得在使用爬虫时要遵守目标网站的robots.txt规则,并设置合理的请求间隔以避免给目标服务器造成过大负担。