Estoy intentando obtener información de "Página de detalles de St. Paul The Apostle". Necesito la dirección, el número de teléfono y la descripción. Se puede acceder a toda esta información a través de etiquetas HTML normales que se pueden desechar usando Nokogiri, sin embargo, encontré un bloque de información en una etiqueta <script>.

<script type="application/ld+json">
          {
          "@context": "http://schema.org",
          "@type": "LocalBusiness",
          "address": {
          "@type":"PostalAddress",
          "streetAddress":"98-16 55th Avenue",
          "addressLocality":"Corona",
          "addressRegion":"NY",
          "postalCode": "11368"             
          },
          "name": "St. Paul The Apostle",
          "telephone":"(718) 271-1100",
          "image": "https://www.foodpantries.org/gallery/3101_st._paul_the_apostle_11368_idu.png",
          "description": "<b>Food Pantry Hours: </b><br>2nd and 4th week of the month <br>8:00am and open until food runs out <br>(usually people line up about 1 hour prior to 8 AM)<br><br><b>For more information, please call. </b><br>"
          }
        </script>

Esperaba usar este bloque de código para raspar toda la información que necesitaba:

def self.scrape_info
  agent = Mechanize.new
  page = agent.get('https://www.foodpantries.org/li/st._paul_the_apostle_11368')
  street_address = agent.page.search('script').text
  puts street_address.to_s
end

¿Cómo puedo hacer esto?

0
Anthony Oglesby 5 dic. 2019 a las 17:34

2 respuestas

La mejor respuesta

Mechanize es excesivo si todo lo que está usando es recuperar una página. Hay muchas gemas de cliente HTTP que lo harán fácilmente, o usarán OpenURI que forma parte de la biblioteca estándar de Ruby.

Esto es lo básico para recuperar la información. Tendrá que averiguar qué script en particular desea, pero los tutoriales de Nokogiri le darán los conceptos básicos. :

require 'json'
require 'nokogiri'
require 'open-uri'

doc = Nokogiri::HTML(open('https://www.foodpantries.org/li/st._paul_the_apostle_11368'))

En este punto, Nokogiri tiene un DOM creado de la página en la memoria.

Busque el nodo <script> que desea y extraiga el texto del nodo:

js = doc.at('script[type="application/ld+json"]').text

at y search son los caballos de batalla para analizar una página. Hay variantes específicas de CSS y XPath, pero generalmente puede usar las versiones genéricas y Nokogiri descubrirá cuál usar. Todos están documentados en la misma página que at y search y los tutoriales.

JSON es inteligente y nos permite usar una abreviatura de JSON[...] para analizar o generar una cadena JSON. En este caso, está analizando una cadena de nuevo en un objeto Ruby, que en este caso es un hash:

JSON[js]
# => {"@context"=>"https://schema.org",
#     "@type"=>"Organization",
#     "url"=>"https://www.foodpantries.org/",
#     "sameAs"=>[],
#     "contactPoint"=>
#      [{"@type"=>"ContactPoint",
#        "contactType"=>"customer service",
#        "url"=>"https://www.foodpantries.org/ar/about",
#        "email"=>"webmaster@foodpantries.org"}]}

Acceder a un par clave / valor particular es simple, al igual que con cualquier otro hash:

foo = JSON[js]
foo['url'] # => "https://www.foodpantries.org/"

La página a la que se refiere tiene varios scripts que coinciden con el selector que utilicé, por lo que querrá filtrar usando un selector más exacto, o iterar sobre las coincidencias y elegir el que desee. Cómo hacerlo está bien documentado aquí en SO usando CSS, XPath y la documentación de Nokogiri.

0
the Tin Man 6 dic. 2019 a las 22:33

Desea analizar aquellos con JSON:

require 'json'
jsons = page.search('script[type="application/ld+json"]').map{|s| JSON.parse(s.content)}
0
pguardiario 6 dic. 2019 a las 02:29