短效代理
隧道代理
套餐购买
提取工具
帮助中心
产品手册
产品介绍
短效代理
隧道代理
常见问题
使用问题
购买问题
产品问题
开发者指南
开发者指南
快速入门
通用功能
API接口
白名单接口
错误码一览
短效代理接口
行业资讯
关于我们
登录
免费注册
控制台
{{ userInfo.sub_user?.name || userInfo.username }}
{{ userInfo.sub_user?.name || userInfo.username }}
个人认证
企业认证
未实名认证
¥
{{ userInfo.money }}
充值
会员中心
未支付订单
退出登录
首页
/
行业资讯
/
2026 Ruby网页抓取器:Nokogiri实战
2026 Ruby网页抓取器:Nokogiri实战
2026-08-24
代理服务选型
国内动态代理
国内HTTP代理
高并发采集
Ruby 不仅适合开发 Web 应用,也可以用来编写轻量、易维护的网页抓取器。其中,Nokogiri 是 Ruby 生态中常用的 HTML/XML 解析库,支持 CSS Selector 和 XPath,适合处理商品列表、资讯页面、公开目录等结构化网页。 本文将通过一个完整案例,介绍如何使用 Nokogiri 请求网页、提取字段、处理分页并导出 CSV,同时说明批量采集时如何接入代理 IP。 ## Nokogiri是什么 Nokogiri 是一个用于解析 HTML 和 XML 文档的 Ruby 库。它可以把网页源码转换为可查询的文档对象,再通过 CSS Selector 或 XPath 定位具体节点。 一套基础的 Ruby 网页抓取流程通常包括: 1. 使用 `Net::HTTP`、`Faraday` 等工具请求网页; 2. 使用 Nokogiri 解析返回的 HTML; 3. 根据页面结构提取标题、价格、链接等字段; 4. 将结果保存到 CSV、JSON 或数据库; 5. 处理分页、重试、限速和代理切换。 需要注意,Nokogiri 负责的是“解析网页”,不会自动执行页面中的 JavaScript。如果目标数据必须等浏览器渲染后才出现,需要配合 Playwright、Selenium 等浏览器自动化工具。 ## 安装Nokogiri 在项目的 `Gemfile` 中加入: ```ruby gem "nokogiri" ``` 然后执行: ```bash bundle install ``` 也可以直接安装: ```bash gem install nokogiri ``` 安装完成后,通过以下代码引入: ```ruby require "nokogiri" require "net/http" require "uri" ``` ## 抓取并解析第一个网页 下面以一个公开列表页为例,提取页面中的标题和链接: ```ruby require "nokogiri" require "net/http" require "uri" url = URI("https://example.com/articles") request = Net::HTTP::Get.new(url) request["User-Agent"] = "Mozilla/5.0 RubyScraper/1.0" request["Accept-Language"] = "zh-CN,zh;q=0.9" response = Net::HTTP.start( url.host, url.port, use_ssl: url.scheme == "https", open_timeout: 5, read_timeout: 10 ) do |http| http.request(request) end unless response.is_a?(Net::HTTPSuccess) raise "请求失败:HTTP #{response.code}" end document = Nokogiri::HTML(response.body) document.css(".article-item").each do |item| title = item.at_css(".article-title")&.text&.strip href = item.at_css("a")&.[]("href") puts "#{title} - #{href}" end ``` 这段代码中,有几个参数值得关注: - `User-Agent`:说明请求端身份,避免使用 Ruby 默认请求头; - `open_timeout`:限制建立连接的等待时间; - `read_timeout`:限制服务器返回内容的等待时间; - `&.`:当节点不存在时返回 `nil`,避免程序直接报错; - `strip`:清除文本两侧多余的空格和换行。 实战中不要只根据浏览器里看到的文字编写选择器,应先检查 HTML 源码,确认数据是否真实存在于响应内容中。 ## CSS Selector和XPath怎么选 Nokogiri 支持 CSS Selector 与 XPath 两种定位方式。 CSS Selector 写法通常更直观: ```ruby document.css(".product-card") document.at_css("h1.product-title") document.css("ul.pagination a") ``` XPath 更适合处理层级复杂或需要根据文本、属性筛选的页面: ```ruby document.xpath("//div[contains(@class, 'product-card')]") document.xpath("//a[contains(text(), '下一页')]") document.xpath("//span[@data-type='price']") ``` 如果页面结构比较规整,可以优先使用 CSS Selector;如果需要按文本内容、相邻节点或复杂属性定位,再考虑 XPath。 ## 提取商品列表并导出CSV 假设页面中的每个商品由 `.product-card` 容器包裹,可以提取名称、价格和详情链接: ```ruby require "nokogiri" require "net/http" require "uri" require "csv" def fetch_html(url) uri = URI(url) request = Net::HTTP::Get.new(uri) request["User-Agent"] = "Mozilla/5.0 RubyScraper/1.0" response = Net::HTTP.start( uri.host, uri.port, use_ssl: uri.scheme == "https", open_timeout: 5, read_timeout: 10 ) do |http| http.request(request) end raise "HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess) response.body end html = fetch_html("https://example.com/products") document = Nokogiri::HTML(html) products = document.css(".product-card").map do |card| { name: card.at_css(".product-name")&.text&.strip, price: card.at_css(".product-price")&.text&.strip, url: card.at_css("a")&.[]("href") } end CSV.open("products.csv", "w", write_headers: true, headers: %w[name price url]) do |csv| products.each do |product| csv << product.values_at(:name, :price, :url) end end puts "共写入 #{products.length} 条商品数据" ``` 如果链接是 `/products/123` 这样的相对路径,可以使用 `URI.join` 补全: ```ruby absolute_url = URI.join("https://example.com", relative_url).to_s ``` 对于价格字段,建议同时保留原始文本和清洗后的数值,避免货币符号、千位分隔符或活动价影响后续分析。 ## 如何处理分页抓取 列表采集通常需要循环访问多个页面。以下示例按页码抓取,并在没有数据时停止: ```ruby all_products = [] 1.upto(20) do |page| url = "https://example.com/products?page=#{page}" html = fetch_html(url) document = Nokogiri::HTML(html) cards = document.css(".product-card") break if cards.empty? cards.each do |card| all_products << { name: card.at_css(".product-name")&.text&.strip, price: card.at_css(".product-price")&.text&.strip } end puts "第 #{page} 页完成,本页 #{cards.length} 条" # 控制请求频率,避免短时间内连续访问 sleep(rand(1.5..3.0)) end ``` 不要默认目标站点一定有固定页数。更稳妥的做法是同时设置最大页数,并根据“下一页”按钮、空列表或重复数据判断是否结束。 ## Ruby抓取器如何接入代理IP 当任务需要按地区获取公开页面、分散批量请求或隔离采集环境时,可以在 `Net::HTTP` 中配置代理。 ```ruby require "net/http" require "uri" target_uri = URI("https://example.com/products") proxy_host = ENV.fetch("PROXY_HOST") proxy_port = ENV.fetch("PROXY_PORT").to_i proxy_user = ENV["PROXY_USER"] proxy_pass = ENV["PROXY_PASS"] http_class = Net::HTTP::Proxy( proxy_host, proxy_port, proxy_user, proxy_pass ) request = Net::HTTP::Get.new(target_uri) request["User-Agent"] = "Mozilla/5.0 RubyScraper/1.0" response = http_class.start( target_uri.host, target_uri.port, use_ssl: true, open_timeout: 5, read_timeout: 10 ) do |http| http.request(request) end puts response.code ``` 代理地址和认证信息不应直接写入代码仓库,可以通过环境变量配置: ```bash export PROXY_HOST="代理服务器地址" export PROXY_PORT="代理端口" export PROXY_USER="代理账号" export PROXY_PASS="代理密码" ``` 在持续采集任务中,代理并不是接入后就无需管理。建议记录每次请求的代理节点、状态码、响应时间和重试次数,以便区分以下问题: - 目标服务器响应较慢; - 代理连接失败或节点不可用; - 页面结构发生变化; - 请求频率过高; - 账号或代理鉴权参数错误。 极安代理可用于 Ruby 数据采集程序的网络出口配置。实际选型时,可以根据目标地区、任务并发量、IP 使用时长和会话保持需求选择对应类型,不建议单纯以 IP 数量判断是否适合任务。 ## 增加重试和异常处理 批量采集不应因为一次超时就终止全部任务。可以为网络异常增加有限次数的重试: ```ruby def fetch_with_retry(url, max_retries: 3) retries = 0 begin fetch_html(url) rescue Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNRESET => error retries += 1 if retries <= max_retries wait_seconds = retries * 2 warn "请求异常:#{error.class},#{wait_seconds} 秒后重试" sleep(wait_seconds) retry end raise end end ``` 重试次数需要设置上限。对于 `404`、`401` 等明确状态,不应无条件重复请求;对于 `429` 或临时性 `5xx` 响应,可以结合 `Retry-After` 响应头和退避时间决定是否重试。 ## 总结 使用 Ruby 构建网页抓取器时,Nokogiri 主要负责 HTML 解析,网络请求、代理配置、分页控制、重试和数据存储则需要由其他模块配合完成。 对于小规模任务,`Net::HTTP + Nokogiri + CSV` 已能覆盖多数静态页面采集需求。任务规模扩大后,应进一步加入请求队列、并发限制、代理健康检查、数据去重和结构变化监控。无论采用何种技术方案,都应遵守目标网站的服务条款、访问规则和适用法律,只采集获得授权或公开允许使用的数据。 ## Nokogiri抓取常见问题 Q:为什么选择器在浏览器里有效,Nokogiri却抓不到? 常见原因是数据由 JavaScript 动态加载。浏览器开发者工具展示的是渲染后的 DOM,而 Nokogiri 解析的是服务器最初返回的 HTML。可以检查网页接口请求,或改用浏览器自动化工具。 Q:网页结构变化后怎么减少维护成本? 不要把所有选择器散落在业务代码中。可以集中定义字段规则,并对标题、列表数量等关键字段增加校验。当连续多个页面提取结果为空时,应触发告警,而不是继续写入空数据。 Q:Nokogiri能抓取HTTPS网页吗? 可以。使用 `Net::HTTP` 时,需要根据 URL 协议设置 `use_ssl: true`。如果通过代理访问 HTTPS 页面,还要确认代理服务支持对应连接方式。 Q:Ruby抓取器需要每次请求都更换代理吗? 不一定。搜索结果采集、分页浏览或登录会话通常需要一定的 IP 连续性;完全随机切换代理可能导致会话丢失。应根据目标网站和任务类型设置轮换周期,而不是机械地每次更换。
上一篇
HTTP代理与HTTPS代理的区别是什么?
下一篇
没有了
热门文章
2026 Ruby网页抓取器:Nokogiri实战
量化分析行业数据洞察:主流量化平台代理IP需求基准
代理IP的定义、分类与常见场景:一篇讲透
Selenium抓取工具怎么用?6步搭好浏览器自动化采集完整流程
IP代理企业采购评估框架:技术自检清单
2026 年再看 HTTP 代理:与 SOCKS5、HTTPS 代理的核心区别
用Excel VBA自动采集网站数据,不装Python也能跑通的实操教程
最新文章
2026 Ruby网页抓取器:Nokogiri实战
量化分析行业数据洞察:主流量化平台代理IP需求基准
代理IP的定义、分类与常见场景:一篇讲透
Selenium抓取工具怎么用?6步搭好浏览器自动化采集完整流程
IP代理企业采购评估框架:技术自检清单
2026 年再看 HTTP 代理:与 SOCKS5、HTTPS 代理的核心区别
用Excel VBA自动采集网站数据,不装Python也能跑通的实操教程
隧道代理配置实战:从零搭建到企业级部署的完整流程
2026 年 AI Agent 自动浏览网页,为什么更依赖稳定访问环境?
requests 报 ProxyError: Cannot connect to proxy,怎么快速定位真正原因?