Ruby爬虫失效:如何获取动态生成网页的HTML并抓取影视列表?
解决Ruby爬虫无法抓取动态生成网页的问题
嘿,我完全懂你时隔两年重启旧项目踩坑的郁闷!原来的爬虫失效核心原因是网页从静态渲染变成了JS动态生成内容,而且网站还加了脚本修改初始DOM,直接用Nokogiri这类静态HTML解析工具肯定拿不到想要的数据。下面给你两个最实用的解决方案:
方案一:用无头浏览器模拟真实访问(最稳妥)
这种方法相当于让Ruby控制一个看不见的浏览器,完整执行页面所有JS代码,最终拿到渲染完成后的真实HTML,完美解决动态内容和DOM被修改的问题。
步骤:
- 安装依赖gem:
gem install capybara selenium-webdriver - 示例代码:
这种方式完全模拟用户浏览行为,不管网站怎么用JS修改DOM、加载内容,都能拿到最终的页面状态。require 'capybara/dsl' require 'nokogiri' # 配置Capybara使用无头Chrome include Capybara::DSL Capybara.default_driver = :selenium_chrome_headless # 访问目标页面 visit '你要爬的节目列表页面URL' # 等待动态内容加载完成(比如等待某个节目元素出现) # 这里替换成你页面中实际存在的动态元素选择器 find('.tv-program-item') # 获取完整渲染后的HTML full_rendered_html = page.html # 用Nokogiri解析提取数据 doc = Nokogiri::HTML(full_rendered_html) # 比如提取所有节目名称 doc.css('.tv-program-item .title').each do |item| puts item.text.strip end
方案二:直接调用网站的API接口(更高效)
很多动态网站的内容其实是通过AJAX请求后端API拿到的JSON数据,然后渲染到页面上。这种方式比无头浏览器快得多,而且资源消耗小。
步骤:
- 找出API接口:
- 打开浏览器开发者工具(F12),切换到「Network」标签,刷新页面。
- 过滤「XHR」或「Fetch」请求,找返回节目列表数据的请求(通常返回JSON格式)。
- 复制这个请求的URL、请求头(比如
User-Agent、Cookie,有些网站需要这些验证)。
- 示例代码:
这种方法的关键是找到正确的API接口,有些网站的API可能有签名或加密,但大部分公开的节目列表API不会太复杂。require 'faraday' require 'json' # 初始化Faraday客户端,添加必要的请求头 conn = Faraday.new( url: '你找到的API接口URL', headers: { 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...', # 复制浏览器的User-Agent 'Cookie' => 'xxx=xxx; yyy=yyy' # 如果需要的话,复制浏览器的Cookie } ) # 发送请求并解析JSON response = conn.get program_data = JSON.parse(response.body) # 直接处理JSON数据,比如提取一周的节目 program_data['weekly_programs'].each do |day| puts "日期:#{day['date']}" day['programs'].each do |prog| puts " #{prog['time']} - #{prog['name']}" end end
关于「所有URL都加载同一初始页面」的问题
这是单页应用(SPA)的典型特征:网站用JS路由处理页面跳转,所有请求都先加载初始HTML,再根据URL的哈希(比如#/week-program)或参数渲染对应内容。用无头浏览器的话,visit对应的URL后,浏览器会自动执行JS路由渲染出正确的页面,直接拿HTML就行;如果用API的话,只要找到对应节目列表的API参数(比如传入日期范围)就能拿到对应数据。
内容的提问来源于stack exchange,提问作者user3285799
相关产品推荐
相关产品推荐

