如何使用Mechanize捕获重定向后的PDF页面最终URL?
解决Mechanize无法获取最终重定向URL的问题
你遇到的问题很常见——那个https://linkinghub.elsevier.com/retrieve/p...其实是一个中间跳转页,它并没有用标准的HTTP 3xx重定向,而是通过HTML的meta刷新标签来完成最终的PDF跳转,而Mechanize默认不会自动处理这类非HTTP协议的重定向。
这里有两种简单的解决方法,推荐第一种最直接的:
方法一:开启Mechanize的meta刷新跟进功能
Mechanize其实自带了处理meta刷新重定向的配置,你只需要在初始化的时候加上follow_meta_refresh = true即可:
link = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi?dbfrom=pubmed&retmode=ref&cmd=prlinks&id=29499174" m = Mechanize.new do |a| a.keep_alive = 1 a.follow_meta_refresh = true # 关键配置:自动跟进meta刷新跳转 end p = m.get(link) uri = p.uri.to_s puts uri # 此时输出的就是最终的PDF下载URL
方法二:手动解析meta刷新标签(适合自定义处理场景)
如果你需要更精细的控制,可以手动提取页面中的meta刷新标签,获取跳转URL:
link = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi?dbfrom=pubmed&retmode=ref&cmd=prlinks&id=29499174" m = Mechanize.new { |a| a.keep_alive = 1 } p = m.get(link) # 查找页面中的meta刷新标签 meta_refresh_tag = p.search('meta[@http-equiv="refresh"]').first if meta_refresh_tag # 提取content属性中的URL部分(格式通常是 "0; url=目标URL") refresh_content = meta_refresh_tag['content'] if refresh_content =~ /url=(.*)/i final_raw_url = $1.strip # 补全相对URL(如果有的话) final_url = p.uri.merge(final_raw_url).to_s puts final_url end end
额外说明
如果遇到的是JavaScript驱动的重定向(比如通过window.location.href跳转),Mechanize本身无法执行JavaScript,这时候你可能需要换用支持JS的工具(比如Watir或Capybara配合浏览器驱动),不过针对NCBI到Elsevier的跳转,第一种方法基本就能解决问题了。
内容的提问来源于stack exchange,提问作者Jackson Gong
相关产品推荐
相关产品推荐

