大家是不是好奇用Groovy写爬虫到底靠不靠谱?简单说,这玩意儿就像给Java插上了翅膀——既能直接用所有Java的牛逼库,又能用更简洁的代码快速搞事。比如用几行代码就能扒网页数据,处理JSON像吃糖一样简单,还能和Redis这些中间件无缝配合。特别适合急需验证想法或者团队里Java老哥多的场景,下面咱就上手整段真实能跑的代码瞧瞧!

下面是一个实用的Groovy爬虫代码,用于爬取图书信息网站并提取数据。这个示例展示了Groovy在爬虫开发中的简洁性和强大功能。
#!/usr/bin/envgroovy
// 导入必要的库
@Grab('org.jsoup:jsoup:1.15.3')
@Grab('org.apache.httpcomponents:httpclient:4.5.13')
@Grab('com.fasterxml.jackson.core:jackson-databind:2.14.2')
importorg.jsoup.Jsoup
importorg.jsoup.nodes.Document
importorg.jsoup.nodes.Element
importorg.jsoup.select.Elements
importorg.apache.http.impl.client.HttpClients
importorg.apache.http.client.methods.HttpGet
importorg.apache.http.client.config.RequestConfig
importorg.apache.http.util.EntityUtils
importcom.fasterxml.jackson.databind.ObjectMapper
importcom.fasterxml.jackson.databind.SerializationFeature
/**
* 图书信息类
*/
classBook{
Stringtitle
Stringauthor
BigDecimalprice
Stringdescription
Integerrating
Stringurl
StringtoString() {
"《${title}》- ${author} - 价格: ${price}元 - 评分: ${rating}星"
}
}
/**
* 网页爬虫类
*/
classBookScraper{
// HTTP客户端配置
privatedefhttpClient
privatedefconfig
privatedefobjectMapper
BookScraper() {
// 配置HTTP客户端(设置超时和代理等)
config=RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(5000)
.build()
httpClient=HttpClients.custom()
.setDefaultRequestConfig(config)
.build()
objectMapper=newObjectMapper()
objectMapper.enable(SerializationFeature.INDENT_OUTPUT)
}
/**
* 获取网页内容
*/
StringfetchPage(Stringurl) {
try{
println"正在抓取: $url"
defhttpGet=newHttpGet(url)
// 设置请求头,模拟浏览器
httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
httpGet.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
defresponse=httpClient.execute(httpGet)
defentity=response.getEntity()
defcontent=EntityUtils.toString(entity)
EntityUtils.consume(entity)
returncontent
}catch(Exceptione) {
println"抓取网页时出错: ${e.message}"
returnnull
}
}
/**
* 解析图书列表页
*/
List<Book>parseBookList(Stringhtml,StringbaseUrl) {
defbooks=[]
try{
Documentdoc=Jsoup.parse(html)
ElementsbookElements=doc.select(".product_pod")// 假设每本书都在这个CSS类中
bookElements.each{Elementelement->
try{
Bookbook=newBook()
// 提取标题
book.title=element.select("h3 a").attr("title")
if(!book.title) {
book.title=element.select("h3 a").text()
}
// 提取作者
book.author=element.select(".author").text()?:"未知作者"
// 提取价格
defpriceText=element.select(".price_color").text()
book.price=priceText?newBigDecimal(priceText.replaceAll("[^\\d.]","")) :0.0
// 提取评分(假设评分用CSS类表示,如star-rating-Five)
defratingClass=element.select(".star-rating").attr("class")
defratingMatch=ratingClass=~/star-rating-(\w+)/
if(ratingMatch) {
defratingMap=[One:1,Two:2,Three:3,Four:4,Five:5]
book.rating=ratingMap[ratingMatch[0][1]]?:0
}
// 提取详情页链接
defrelativeUrl=element.select("h3 a").attr("href")
book.url=baseUrl+relativeUrl
// 获取图书详情
fetchBookDetails(book)
books<<book
println"已解析: ${book.title}"
}catch(Exceptione) {
println"解析单本书时出错: ${e.message}"
}
}
}catch(Exceptione) {
println"解析图书列表时出错: ${e.message}"
}
returnbooks
}
/**
* 获取图书详细信息
*/
voidfetchBookDetails(Bookbook) {
try{
defhtml=fetchPage(book.url)
if(html) {
Documentdoc=Jsoup.parse(html)
// 提取描述
defdescriptionElement=doc.select("#product_description + p")
if(descriptionElement) {
book.description=descriptionElement.text()
}
}
}catch(Exceptione) {
println"获取图书详情时出错: ${e.message}"
}
}
/**
* 保存结果到JSON文件
*/
voidsaveToJson(List<Book>books,Stringfilename) {
try{
objectMapper.writeValue(newFile(filename),books)
println"结果已保存到: ${filename}"
}catch(Exceptione) {
println"保存结果时出错: ${e.message}"
}
}
/**
* 关闭HTTP客户端
*/
voidclose() {
httpClient.close()
}
}
/**
* 主程序
*/
defmain() {
// 初始化爬虫
defscraper=newBookScraper()
try{
// 要爬取的网站URL(这里以虚构的图书网站为例)
defbaseUrl="https://books.example.com"
defstartUrl="${baseUrl}/catalogue/page-1.html"
// 获取网页内容
defhtml=scraper.fetchPage(startUrl)
if(html) {
// 解析图书列表
defbooks=scraper.parseBookList(html,baseUrl)
// 打印结果
println"\n爬取结果:"
books.eachWithIndex{book,index->
println"${index+1}. ${book}"
if(book.description) {
println" 描述: ${book.description.length()>100?book.description.substring(0,100)+'...':book.description}"
}
println()
}
// 保存结果到JSON文件
scraper.saveToJson(books,"books.json")
println"共爬取 ${books.size()} 本书籍"
}else{
println"未能获取网页内容"
}
}finally{
// 确保关闭HTTP客户端
scraper.close()
}
}
// 运行主程序
main()
代码说明
这个Groovy爬虫示例具有以下特点:
1、完整的爬虫功能:
发送HTTP请求并处理响应
解析HTML内容提取所需数据
处理异常和错误情况
保存结果到JSON文件
2、使用Groovy的优势:
简洁的语法和强大的集合操作
直接使用Java生态库(Jsoup、HttpClient、Jackson)
灵活的闭包和DSL风格代码
无需编译,可直接运行
3、实用功能:
设置超时和请求头模拟浏览器
错误处理和日志输出
数据清洗和转换
结构化数据存储
运行方法
1、确保已安装Groovy
2、将代码保存为book_scraper.groovy
3、运行命令:groovy book_scraper.groovy
扩展建议
1、添加代理支持以避免IP被封
2、实现分页爬取功能
3、添加并发处理以提高爬取效率
4、集成数据库存储代替文件存储
5、添加定时任务支持定期爬取
这个示例展示了Groovy在爬虫开发中的简洁性和强大功能,特别适合需要快速开发和与Java生态系统集成的项目。
看出来了吧?Groovy搞爬虫真是又狠又灵活!代码写得比Java清爽十倍,底层还能调用所有Java生态的硬核工具库。无论是快速抓数据还是集成到现有Java系统里都特别顺手。不过记得爬数据要讲武德,控制频率加异常处理,毕竟咱不是暴力爬虫。用这招去折腾数据吧,绝对爽到飞起!