2015-04-27 2 views
0

J'ai une application Rails 4 servant des données JSON à un client frontal BackboneJS. Le backend récupère du contenu de Craigslist et le sert au frontend en tant que JSON. Localement, en développement, cela fonctionne comme prévu.Heroku lance OpenURI :: HTTPError (403 Interdit):

Sur Heroku, la mise en page de l'application est correctement diffusée et les éléments semblent se charger correctement. Ce n'est que lorsque backboneJS demande des données pour remplir la vue appropriée, et là l'application échoue en raison de l'erreur OpenURI.

Plus précisément, openURI revient sans cesse le

OpenURI::HTTPError (403 Forbidden) 

lors de l'exécution de la ligne suivante dans le contrôleur Rails:

open("#{clist.url}") 

J'ai passé plusieurs heures à essayer différentes solutions « résolus » J'ai trouvé sur Stack Overflow et Github et juste en essayant de regarder à travers les journaux Heroku pour d'autres erreurs, mais l'erreur reste peu importe ce que les «solutions» suggérées que j'essaie.

A partir de maintenant, j'ai essayé les solutions proposées ci-dessous, ainsi que plusieurs autres les stupides:

  • open-uri requis dans mon contrôleur d'application
  • Ajout de la touche « User-Agent » à mon appel ouvert méthode
  • changé la clist.url de « https » à « http » pour éviter les redirections

en outre, l'application est en avant et ne nécessite pas de droit d'authentification au moment ou l'autre.

En dehors de Stack Overflow et github, je n'ai pas trouvé de solutions suggérées ailleurs. Toute aide avec des suggestions sur d'autres conseils de débogage pour essayer ou des solutions suggérées serait extrêmement appréciée. Je suis relativement nouveau à Heroku, je suis toujours familiarisé avec les problèmes de débogage sur un moteur de production à distance.

Voici le code pertinent qui vient de Craigslist (ne me jugez pas trop durement.)/La plupart de cette méthode est paramétrée pour être refactorisée et mise dans sa propre classe/modèle, où elle appartient):

def index 
    @listings = [] 

    #Retrieve job listings from Craigslist (see method sync_list below ...) 
    @raw_listings = sync_clist 

    # filters applied at this point ... 
    # and they transform @raw_listings to ... 
    # the array @listings 

    render json: @listings 
end 

def sync_clist 
    #@search_items = SearchItem.all 
    @search_items = SearchItem.all[0..1] 
    site = @sites[0] 

    # in the Craigslist HTML, the second element in the returned job listing # is the better one to use 
    href_idx = 1 

    ##### LINE 123 is the next one: 
    @search_items.each_with_index do |search_item, idx| 
     puts "#{search_item.url.upcase}" 

     ##### LINE 125 ... FAILURE_HERE? ***************** 
     html = open("#{search_item.url}", 'User-Agent' => "Ruby/#{RUBY_VERSION}") 
     page = Nokogiri::HTML(html.read, nil, 'utf-8') 
     category_idx = idx % 4 
     isNearby_listing = false  #also capture 'nearby' jobs on Craigslist 

     page.css(site[:joblist_css])[0..-2].each_with_index do |listing, i| 
     # convert the relative url in the list to a full-url 
     locale_idx = idx/@clist_locales.length 
     listing_url = listing.css('a')[href_idx]['href'] 

     # Craigslist only lists the relative path of job urls - relative to the 
     # current search location. The 'More Local' items, however, return the 
     # full url. 
     if !isNearby_listing 
      posting_url = site[:protocol] + site[:locales][locale_idx] + "." + site[:host] + listing_url 
     else 
      posting_url = listing_url 
     end 

     # Once the appropriate heading is reached, the 'More Local' listings 
     # items begin appearing 
     if listing.next_sibling.node_name == 'h4' 
      isNearby_listing = true 
     end 

     posting_date = listing.css('time')[0]['datetime'] 
     job_listing = { :source  => site[:sitename].upcase, 
         :title  => listing.css('a')[href_idx].text, 
         :url   => posting_url, 
         :listing_id => listing["data-pid"], 
         :location  => @clist_locales[locale_idx], 
         :content  => "", 
         :telecommute => "", 
         :contract  => "", 
         :pt_ft  => "", 
         :favorite  => false, 
         :posted_date => posting_date, 
         :category  => @clist_categories[category_idx], 
         :apply_state => "new" 
     } 

     @new_listings << job_listing 
     end 
    end 
    @new_listings 
    end 

Voici la sortie de mes journaux Heroku dans le cas où il aide:

`` `

2015-04-27T03:47:14.611278+00:00 app[web.1]: => Rails 4.0.8 application starting in production on http://0.0.0.0:43688 
2015-04-27T03:47:14.611280+00:00 app[web.1]: => Run `rails server -h` for more startup options 
2015-04-27T03:47:14.611310+00:00 app[web.1]: Started GET "/" for 24.5.106.52 at 2015-04-27 03:47:14 +0000 
2015-04-27T03:47:14.611272+00:00 app[web.1]: => Booting WEBrick 
2015-04-27T03:47:14.611281+00:00 app[web.1]: => Ctrl-C to shutdown server 
2015-04-27T03:47:14.664777+00:00 app[web.1]: Rendered app/root.html.erb within layouts/application (0.5ms) 
2015-04-27T03:47:14.661735+00:00 app[web.1]: Processing by AppController#root as HTML 
2015-04-27T03:47:14.664783+00:00 app[web.1]: Rendered app/root.html.erb within layouts/application (0.5ms) 
2015-04-27T03:47:14.674604+00:00 app[web.1]: Completed 200 OK in 13ms (Views: 12.3ms | ActiveRecord: 0.0ms) 
2015-04-27T03:47:14.674612+00:00 app[web.1]: Completed 200 OK in 13ms (Views: 12.3ms | ActiveRecord: 0.0ms) 
2015-04-27T03:47:14.611302+00:00 app[web.1]: Started GET "/" for 24.5.106.52 at 2015-04-27 03:47:14 +0000 
2015-04-27T03:47:14.661749+00:00 app[web.1]: Processing by AppController#root as HTML 
2015-04-27T03:47:15.943141+00:00 heroku[router]: at=info method=GET path="/assets/application-45c34fbd86efe641e061caa3b34737d7.css" host=APPNAME.herokuapp.com request_id=dbf8473e-2880-42f6-8ef4-11e0da7141b4 fwd="24.5.106.52" dyno=web.1 connect=2ms service=73ms status=200 bytes=569692 
2015-04-27T03:47:15.944069+00:00 heroku[router]: at=info method=GET path="/assets/application-537f60efd0378faaddaea08875f25055.js" host=APPNAME.herokuapp.com request_id=5c7cf6db-393f-434e-a494-d3664d31a20f fwd="24.5.106.52" dyno=web.1 connect=2ms service=70ms status=200 bytes=965489 
2015-04-27T03:47:17.631614+00:00 app[web.1]: Started GET "/posts" for 24.5.106.52 at 2015-04-27 03:47:17 +0000 
2015-04-27T03:47:17.631624+00:00 app[web.1]: Started GET "/posts" for 24.5.106.52 at 2015-04-27 03:47:17 +0000 
2015-04-27T03:47:17.636842+00:00 app[web.1]: Processing by PostsController#index as JSON 
2015-04-27T03:47:17.636831+00:00 app[web.1]: Processing by PostsController#index as JSON 
2015-04-27T03:47:17.665568+00:00 app[web.1]: HTTP://SFBAY.CRAIGSLIST.ORG/SEARCH/SOF?QUERY=RAILS 
2015-04-27T03:47:18.048174+00:00 heroku[router]: at=info method=GET path="/posts" host=APPNAME.herokuapp.com request_id=a2724fb9-6872-4435-8dfc-0df1b73fb761 fwd="24.5.106.52" dyno=web.1 connect=2ms service=417ms status=500 bytes=330 
2015-04-27T03:47:18.042116+00:00 app[web.1]: Completed 500 Internal Server Error in 405ms 
2015-04-27T03:47:18.043586+00:00 app[web.1]: OpenURI::HTTPError (403 Forbidden): 
2015-04-27T03:47:18.042129+00:00 app[web.1]: Completed 500 Internal Server Error in 405ms 
2015-04-27T03:47:18.043590+00:00 app[web.1]: app/controllers/posts_controller.rb:123:in `each' 
2015-04-27T03:47:18.043588+00:00 app[web.1]: app/controllers/posts_controller.rb:125:in `block in sync_clist' 
2015-04-27T03:47:18.043593+00:00 app[web.1]: app/controllers/posts_controller.rb:123:in `sync_clist' 
2015-04-27T03:47:18.043584+00:00 app[web.1]: 
2015-04-27T03:47:18.043591+00:00 app[web.1]: app/controllers/posts_controller.rb:123:in `each_with_index' 
2015-04-27T03:47:18.043596+00:00 app[web.1]: 
2015-04-27T03:47:18.043594+00:00 app[web.1]: app/controllers/posts_controller.rb:53:in `index' 
2015-04-27T03:47:18.043597+00:00 app[web.1]: 
2015-04-27T03:47:18.043602+00:00 app[web.1]: 
2015-04-27T03:47:18.043604+00:00 app[web.1]: app/controllers/posts_controller.rb:125:in `block in sync_clist' 
2015-04-27T03:47:18.043603+00:00 app[web.1]: OpenURI::HTTPError (403 Forbidden): 
2015-04-27T03:47:18.043606+00:00 app[web.1]: app/controllers/posts_controller.rb:123:in `each' 
2015-04-27T03:47:18.043607+00:00 app[web.1]: app/controllers/posts_controller.rb:123:in `each_with_index' 
2015-04-27T03:47:18.043610+00:00 app[web.1]: app/controllers/posts_controller.rb:53:in `index' 
2015-04-27T03:47:18.043609+00:00 app[web.1]: app/controllers/posts_controller.rb:123:in `sync_clist' 
2015-04-27T03:47:18.043613+00:00 app[web.1]: 
2015-04-27T03:47:18.043611+00:00 app[web.1]: 

` ``

+0

Salut et bienvenue à empiler débordement. Pouvez-vous modifier votre question et ajouter des extraits de code pertinents? Par exemple, votre erreur 500 dans les journaux fait référence à l'action index de posts_controller ... ce qui signifie que je commencerais à chercher. –

+0

De plus, vérifier simplement: 'host = APPNAME.herokuapp.com' est-ce une obfuscation délibérée de votre part (ce qui est bien btw), ou avez-vous accidentellement eu 'APPNAME' dedans? :) –

+1

APPNAME est une obfuscation. Je vais ajouter le code du contrôleur correspondant dans une seconde. – juan8a

Répondre

1

En prenant la suggestion de @ TarynEast et en exécutant du code d'application dans la console Heroku, je suis passé à l'utilisation de la bibliothèque 'net/http' au lieu de 'open-uri' pour récupérer la page web Craigslist. Le message suivant a été renvoyé par Craigslist lors de l'utilisation « net/http »:

"This IP has been automatically blocked.\nIf you have questions, please email: [email protected]\n" 

Donc, apparemment, que ce soit toutes les adresses IP Heroku ont été bloqués, ou, plus probablement, il est juste mon application spécifique qui a été bloqué même Bien que mon application pings seulement craigslist au plus 8 fois par site charge. Peut-être que c'était assez pour le bloquer depuis Craigslist est une cible très populaire de grattage des applications. Quoi qu'il en soit, mystère résolu quant à savoir pourquoi l'erreur 403. Au moins, l'application fonctionne toujours localement.

[Mise à jour:] Selon une recherche rapide sur Google, Craigslist bloque l'ensemble des adresses IP AWS et Heroku, entre autres. Voir SO question ici: Craigslist blocking Heroku/AWS

+0

ha! Yay. Eh bien au moins vous savez pourquoi ... –

+0

@ juan8a Avez-vous trouvé une autre façon de gratter Craigslist? –

+0

@ HolgerEdwardWardlowSindbæk - d'après ce que j'ai pu savoir, vous pouvez le racler tant que l'adresse IP du serveur qui effectue le raclage n'a pas déjà été bannie (par exemple votre machine locale). Tous Heroku et AWS (probablement Google Cloud, Digital Ocean, le cloud de Microsoft, etc) sont tous interdits AFAIK ... mais votre adresse IP locale devrait aller bien tant que Craigslist ne vous a pas déjà signalé pour abus. Vérifiez leurs consignes d'utilisation pour vous assurer que vous ne respectez pas leurs "règles d'utilisation". – juan8a

0

J'ai eu un problème similaire quand j'ai eu une application Rails hébergée sur Heroku ouvrant un fichier détenu sur S3. J'ai eu la même erreur parce que l'URL était erronée.