我正在做一个抓取练习,并尝试使用 Nokogiri 从网站上抓取海报。
但是我得到了这个: https://s.lrbxd.com/static/img/empty-poster-500.825678f0.png
为什么?
这是我试过的:
url = "https://letterboxd.com/film/glass-onion-a-knives-out-mystery/"
serialized_html = URI.open(url).read
html = Nokogiri::HTML.parse(serialized_html)
title = html.search('.headline-1').text.strip
overview = html.search('.truncate p').text.strip
poster = html.search('.film-poster img').attribute('src').value
{
title: title,
overview: overview,
poster_url: poster,
}
这与您的红宝石代码无关。
如果您在终端中运行类似
curl https://letterboxd.com/film/glass-onion-a-knives-out-mystery/
您可以看到输出的 HTML 没有您要查找的图像。你可以在你的浏览器中看到,因为在初始加载之后一些 javascript 运行并加载更多资源。
加载您要查找的图像的 ajax 调用是 https://letterboxd.com/ajax/poster/film/glass-onion-a-knives-out-mystery/std/500x750/?k=0c10a16c
使用浏览器的网络检查器,您将能够识别网站的不同部分以及每个部分的加载方式。
Nokogiri 不执行 Javascript,但是链接必须存在,或者至少必须有指向返回链接的某些 API 的链接。
我要搜索它的第一个地方是图像元素或其父元素的数据属性,但是在这种情况下,它与有关电影的其他一些有趣数据一起隐藏在内联 Javascript 中。
首先使用 curl
或 wget
下载网页并在文本编辑器中打开文件以查看 Nokogiri 看到的内容。搜索你知道的关于文件的东西,我搜索了图像 url 的 ce7ed2a83f
部分并找到了 JSON.
然后可以这样提取数据:
require 'nokogiri'
require 'open-uri'
require 'json'
url = "https://letterboxd.com/film/glass-onion-a-knives-out-mystery/"
serialized_html = URI.open(url).read
html = Nokogiri::HTML.parse(serialized_html)
data_str = html.search('script[type="application/ld+json"]').first.to_s.gsub("\n",'').match(/{.*}/).to_s
data = JSON.parse(data_str)
data['image']