h2oGPT命令行工具终极指南:5个高效使用AI模型的技巧
Hickory项目实战:构建一个简易网页爬虫与数据提取工具
【免费下载链接】hickory HTML as data 项目地址: https://gitcode.com/gh_mirrors/hic/hickory
Hickory是一个强大的HTML解析与处理库,能将HTML文档转换为Clojure数据结构,支持解析、转换和生成HTML。本教程将带你使用Hickory构建一个高效的网页爬虫与数据提取工具,无需复杂代码即可轻松处理网页数据。
快速了解Hickory核心功能
Hickory作为HTML处理工具,主要提供三大核心能力:
- HTML解析:将原始HTML字符串转换为结构化数据
- 数据转换:支持Hiccup向量格式与Hickory DOM映射格式互转
- 数据提取:通过CSS风格选择器快速定位和提取目标数据
Hickory的设计理念是"HTML as data",将网页内容转化为易于操作的Clojure数据结构,这使得数据处理变得直观而高效。
环境准备:从零开始搭建开发环境
安装Hickory依赖
在项目的project.clj中添加Hickory依赖:
[org.clj-commons/hickory "0.7.3"]
如果你使用Clojure CLI工具,在deps.edn中添加:
org.clj-commons/hickory {:mvn/version "0.7.3"}
项目结构概览
典型的Hickory项目结构如下:
src/
clj/ ; Clojure代码
hickory/
core.clj ; 核心解析功能
cljc/ ; 跨平台代码
hickory/
convert.cljc ; 格式转换功能
select.cljc ; 选择器功能
render.cljc ; HTML渲染功能
test/ ; 测试代码
核心功能解析:HTML解析与数据转换
解析HTML文档
使用hickory.core/parse函数解析完整HTML文档:
(use 'hickory.core)
(def html-content "<html><body><h1>Hello Hickory</h1><p>HTML parsing made easy</p></body></html>")
(def parsed-doc (parse html-content))
对于HTML片段,使用parse-fragment函数:
(def fragment (parse-fragment "<div class='article'><p>First paragraph</p><p>Second paragraph</p></div>"))
数据格式转换
Hickory支持两种主要数据格式:
- Hiccup格式:紧凑的向量表示法,适合编写HTML
(as-hiccup parsed-doc)
; 返回: ([html {} [head {}] [body {} [h1 {} "Hello Hickory"] [p {} "HTML parsing made easy"]]])
- Hickory格式:详细的映射结构,适合数据处理
(as-hickory parsed-doc)
; 返回: {:type :document, :content [{:type :element, :tag :html, ...}]}
Hickory格式的节点结构包含以下关键字:
:type:节点类型(:comment, :document, :element等):tag:元素标签(仅元素节点):attrs:属性映射(仅元素节点):content:子节点向量
实战开发:构建网页数据提取工具
基本爬虫框架搭建
结合HTTP客户端和Hickory,构建一个简单的网页爬虫:
(use 'hickory.core)
(require '[clj-http.client :as client])
(require '[hickory.select :as s])
(defn fetch-and-parse [url]
(-> (client/get url)
:body
parse
as-hickory))
使用选择器提取数据
Hickory的选择器功能(hickory.select命名空间)提供了强大的数据提取能力:
常用选择器函数
tag:按标签选择元素id:按ID选择元素class:按类名选择元素attr:按属性选择元素child:选择直接子元素descendant:选择后代元素
提取示例:获取网页标题
(defn extract-title [htree]
(-> (s/select (s/descendant (s/tag :head) (s/tag :title)) htree)
first
:content
first))
; 使用方法
(def site-htree (fetch-and-parse "https://example.com"))
(extract-title site-htree) ; 返回网页标题文本
提取示例:获取所有链接
(defn extract-links [htree]
(map #(get-in % [:attrs :href])
(s/select (s/tag :a) htree)))
; 获取所有链接
(extract-links site-htree)
高级数据提取:组合选择器
通过组合多个选择器,可以精确定位目标数据:
; 选择class为"article"的div中的所有p标签
(def article-paragraphs
(s/select (s/descendant (s/class :article) (s/tag :p)) site-htree))
; 提取带特定属性的图片
(def product-images
(s/select (s/and (s/tag :img) (s/attr :data-product-id)) site-htree))
数据处理与转换:从HTML到结构化数据
处理提取结果
将提取的原始数据转换为结构化格式:
(defn extract-articles [htree]
(map (fn [article]
{:title (-> (s/select (s/tag :h2) article) first :content first)
:content (->> (s/select (s/tag :p) article)
(map :content)
(map first)
(clojure.string/join " "))
:date (-> (s/select (s/class :date) article) first :content first)})
(s/select (s/class :article) htree)))
使用Zipper修改HTML结构
Hickory提供Zipper功能,可以方便地修改HTML结构:
(require '[hickory.zip :as hzip])
(require '[clojure.zip :as zip])
(defn add-css-class [htree selector class]
(let [zip (hzip/hickory-zip htree)]
(-> (zip/root
(loop [loc zip]
(if (zip/end? loc)
loc
(if (s/select? selector loc)
(recur (zip/edit loc #(update % :attrs assoc :class (str (:class (:attrs %)) " " class)))
(recur (zip/next loc)))))))))
完整案例:构建一个简单的产品信息爬虫
下面是一个完整的示例,从电子商务网站提取产品信息:
(ns product-scraper
(:require [hickory.core :as hickory]
[hickory.select :as s]
[clj-http.client :as client]
[clojure.string :as str]))
(defn fetch-page [url]
(-> (client/get url {:headers {"User-Agent" "Mozilla/5.0"}})
:body
hickory/parse
hickory/as-hickory))
(defn extract-products [htree]
(map (fn [product]
{:name (-> (s/select (s/descendant (s/class :product-name) (s/tag :a)) product)
first :content first str/trim)
:price (-> (s/select (s/class :product-price) product)
first :content first str/trim)
:image (-> (s/select (s/tag :img) product)
first :attrs :src)
:rating (-> (s/select (s/class :rating) product)
first :attrs :data-rating)})
(s/select (s/class :product-item) htree)))
(defn -main [& args]
(let [url (first args)
htree (fetch-page url)
products (extract-products htree)]
(doseq [product products]
(println (str/join "\t" [(:name product) (:price product) (:rating product)])))))
最佳实践与性能优化
选择合适的数据格式
- Hiccup格式:适合生成HTML或简单的结构转换
- Hickory格式:适合复杂的数据提取和分析
优化选择器性能
- 避免过深的嵌套选择器
- 优先使用ID和标签选择器,后使用类选择器
- 对大型文档,考虑分块处理
处理动态内容
对于JavaScript渲染的内容,可以结合Headless浏览器:
; 使用PhantomJS或Selenium获取动态内容
(defn fetch-dynamic-page [url]
; 实现略,需集成外部工具
)
总结与扩展学习
通过本教程,你已经掌握了使用Hickory构建网页爬虫和数据提取工具的基本技能。Hickory的强大之处在于将HTML转换为易于处理的数据结构,让复杂的网页数据提取变得简单直观。
进一步学习资源
- API文档:API.md
- 选择器功能:hickory.select
- 格式转换:hickory.convert
项目扩展方向
- 添加异步请求支持
- 实现数据持久化存储
- 构建可视化数据展示界面
- 开发定时爬取任务
Hickory为网页数据处理提供了强大而灵活的工具集,无论是简单的数据提取还是复杂的HTML转换,都能轻松应对。开始你的Hickory之旅,探索网页数据的无限可能吧!
【免费下载链接】hickory HTML as data 项目地址: https://gitcode.com/gh_mirrors/hic/hickory
更多推荐

所有评论(0)