2017-03-20 1 views
0

J'essaie de créer un site d'information, qui montre au visiteur toutes les offres d'un marchand spécifique sur cette page spécifique. J'ai réussi à extraire les titres de la première page et à intégrer une itération d'URL dans un tableau. Mon code devrait prendre chaque URL et la coller dans le grattoir, énumérer les éléments de cette page, parcourir jusqu'à la page suivante, gratter les titres et les attacher à la liste récente, et ainsi de suite.Comment parcourir des pages d'un site à partir de Rails et Nokogiri

Mon contrôleur ressemble à ceci:

class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 

    class Entry 
    def initialize(title) 
     @title = title 
    end 
    attr_reader :title 
    end 


    def scrape_mydealz 
    require 'open-uri' 
    urlarray = Array.new 
    # --------------------------------------------------------------- URL erstellen 
    pagination = '&page=1' 
    count = [1, 2] 
    count.each do |i| 
     base_url = "https://www.mydealz.de/search?q=media+markt" 
     pagination = "&page=#{i}" 
     combination = base_url + pagination 
     urlarray << combination 
    end 
    # ---------------------------------------------------------------/URL erstellen 

    urlarray.each do |test| 
     doc = Nokogiri::HTML(open("#{test}")) 
     entries = doc.css('article.thread') 
     @entriesArray = [] 
     entries.each do |entry| 
      title = entry.css('a.vwo-thread-title').text 
     @entriesArray << Entry.new(title) 
     end 
    end 
    render template: 'scrape_mydealz' 
    end 
end 

Avec ce code, il itère à la page 2 et affiche le résultat de éraflure de la page 2 uniquement.

Le résultat se trouve ici: https://mm-scraper-neevoo.c9users.io/

+0

thx Nikita, qui a fonctionné –

+0

S'il vous plaît lire "[mcve]". Nous ne pouvons pas exécuter votre code et nous montrer le problème. Nous avons besoin du code _minimum_ démontrant le problème, ainsi que les données d'entrée minimales requises pour le dupliquer et votre sortie requise. Sans cela, nous devons imaginer des données et des résultats qui aboutissent à des réponses inexactes et n'aident personne. Un lien vers un résultat ne nous aide pas, ni d'autres, car les liens pourrissent puis se brisent, ce qui entraîne des questions absurdes. Rappelez-vous, SO n'est pas une liste de discussion, c'est un livre de référence en ligne pour résoudre des problèmes pour les autres dans le futur. –

+0

Je recommanderais d'apprendre à utiliser la classe URI pour manipuler les URI. Il sait comment gérer les cas de coin qui vont causer des problèmes. Ne faites pas '" # {test} "'. 'test' est déjà une chaîne donc utilisez-la sans la coller dans une chaîne littérale et l'interpoler. Vous définissez 'pagination = '& page = 1'' puis faites' pagination = "& page = # {i}" '; supprimez le premier, mais mieux, apprenez à utiliser l'URI et laissez-le construire la requête. 'entry.css ('a.vwo-thread-title'). text' causera des problèmes si plusieurs' 'a.vwo-thread-title'' sont trouvés. Utilisez 'at (...). Text' s'il n'y en a qu'un ou' entry.css (...). Map (&: text) '. –

Répondre

0

Vous REINITIALIZE @entriesArray à chaque itération. La solution pour vous plus facile, pour déplacer l'initialisation en dehors de la boucle

@entriesArray = [] 

urlarray.each do |test| 
    doc = Nokogiri::HTML(open("#{test}")) 
    entries = doc.css('article.thread') 
    entries.each do |entry| 
     title = entry.css('a.vwo-thread-title').text 
     @entriesArray << Entry.new(title) 
    end 
end 
0

Ce n'est pas testé mais il est l'idée générale j'utiliser pour numériser un site avec deux pages et d'accumuler les titres:

require 'open-uri' 

BASE_URL = 'https://www.mydealz.de/search?q=media+markt&page=1' 

def scrape_mydealz 

    urls = [] 
    2.times do |i| 
    url = URI.parse(BASE_URL) 
    base_query = URI::decode_www_form(url.query).to_h 
    base_query['page'] = 1 + i 
    url.query = URI.encode_www_form(base_query) 
    urls << url 
    end 

    @entries_array = [] 
    urls.each do |url| 
    doc = Nokogiri::HTML(open(url)) 
    doc.css('article.thread').each do |entry| 
     @entries_array << Entry.new(entry.at('a.vwo-thread-title').text) 
    end 
    end 
    render template: 'scrape_mydealz' 
end 

Soyez prudent en utilisant text avec search, css ou xpath:

doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p>foo</p> 
    <p>bar</p> 
    </body> 
</html> 
EOT 

doc.search('p').text # => "foobar" 
doc.search('p').map(&:text) # => ["foo", "bar"] 

Notez que le premier r esult a concaténé le contenu des balises <p>. Essayer de les séparer ensuite n'est généralement pas possible.