You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby中通过Web Server/TCP sockets传输爬虫采集的数据

问题解答

问题a:Rails中scraper.rb的存放规范

  • 如果你这个爬虫是会被Rails业务逻辑(比如控制器、定时任务)频繁调用的服务类,统一放到app/services/目录下,命名为scraper_service.rb,类名定义为ScraperService,符合Rails服务对象的约定,Rails会自动加载该目录下的文件,无需手动require。
  • 如果这个爬虫是独立的、仅偶尔手动执行的脚本类工具,放到lib/目录下即可,使用时需要手动require引入。

问题b:服务端返回采集数据的实现方法

分两种场景说明:

场景1:沿用你当前的原生TCPServer实现

你现在的代码无法被Postman正常访问的核心原因是:没有遵循HTTP协议规范,Postman发送的是标准HTTP请求,但你的服务只返回了裸数据,没有HTTP响应头,客户端无法识别。只需要修改返回内容的结构,补全HTTP头即可:

  1. 首先返回HTTP状态行:HTTP/1.1 200 OK
  2. 然后返回必要的响应头,比如内容类型、内容长度,这里返回JSON的话设Content-Type: application/json
  3. 空一行,再返回序列化后的采集数据
    另外你现在每次请求都会重新爬一遍所有网站,响应会非常慢,建议可以加缓存,比如定时爬取存在内存或者数据库里,请求时直接返回缓存数据。

场景2:接入Rails框架的实现

  1. 把爬虫逻辑封装到app/services/scraper_service.rb的run方法中,方法返回采集到的数组
  2. 新建一个控制器,比如app/controllers/scrapes_controller.rb,写一个action比如index,调用ScraperService.run,然后用render json: 结果返回数据
  3. 在config/routes.rb里加路由配置:get '/scrape', to: 'scrapes#index'
  4. 启动Rails服务后,请求http://你的ip:3000/scrape就能拿到JSON格式的采集数据。

问题c:ports、sockets、routing的功能关系

  • 端口(ports):操作系统层面的网络标识,是0-65535的数字,用来区分同一台服务器上运行的不同网络应用,你开服务占用2000端口,其他应用就不能再用这个端口,相当于服务器的「门牌号」,外部请求要先找到对应端口才能和目标应用通信。
  • 套接字(sockets):应用和操作系统网络栈交互的接口,是网络通信的端点,一个socket对应唯一的「IP+端口」组合,负责在客户端和服务端之间传输二进制数据,相当于门旁边的「邮箱」,所有进出这个端口的数据都要通过socket收发。
  • 路由(routing):应用层的请求分发规则,同一个端口的socket会收到很多不同的请求(比如请求路径是/scrape还是/health,请求方法是GET还是POST),路由就是用来把这些请求匹配到对应的处理逻辑上,相当于进了门之后的「房间号」,决定你这次请求要执行哪段代码、返回什么内容。

现有代码修改后的可用版本
require 'socket'
require 'mechanize'
require 'awesome_print'
require 'json'

port = ENV.fetch("PORT",2000).to_i
server = TCPServer.new(port)
puts "Listening on port #{port}..."
puts "Current Time : #{Time.now}"

# 提前爬一次缓存,避免每次请求都重爬,你也可以加定时任务定期更新缓存
def scrape_data
  general_sites = [
    "https://www.lovebscott.com/",
    "https://bleacherreport.com/",
    "https://balleralert.com/",
    "https://peopleofcolorintech.com/",
    "https://afrotech.com/",
    "https://bossip.com/",
    "https://www.itsonsitetv.com/",
    "https://theshaderoom.com/",
    "https://shadowandact.com/",
    "https://hollywoodunlocked.com/",
    "https://www.essence.com/",
    "http://karencivil.com/",
    "https://www.revolt.tv/"
  ]     
  holder=[]
  agent = Mechanize.new
  general_sites.each do |site|
    page=agent.get(site);
    newRet = page.search('a')
    newRet.each do |e|
      data = e.attr('href').to_s
      if(data.length > 50)
        holder.push(data)
      end
    end
    pp holder.length.to_s + " [ posts total] ==> Now Scraping -->  " + site
  end
  holder
end

# 启动时先缓存数据
cached_data = scrape_data

loop do
  client = server.accept
  # 读取请求行,忽略请求内容简单处理,你也可以在这里解析请求路径做路由分发
  request_line = client.gets
  next unless request_line

  # 序列化数据为JSON
  response_body = cached_data.to_json
  # 补全HTTP响应头
  response = <<~HTTP
    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: #{response_body.bytesize}
    Connection: close

    #{response_body}
  HTTP

  client.write(response)
  client.close
end

修改后启动服务,用Postman访问http://localhost:2000就能拿到JSON格式的采集数据,如果要让同一局域网的同事访问,把localhost换成你机器的局域网IP即可。


内容的提问来源于stack exchange,提问作者jMwofford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 22:27:03