【问题标题】:Having problems with Ruby file from Dashing来自 Dashing 的 Ruby 文件有问题
【发布时间】:2013-11-23 12:51:29
【问题描述】:

我在使用 twitter_user.rb 时遇到问题,它应该获取给定 Twitter 用户名的推文、关注者和关注的数量。

我假设我应该将第 9 行中的 TWITTER_USERNAME 替换为我感兴趣的 Twitter 用户名。我这样做了并开始冲刺,但我得到了:

scheduler caught exception:
undefined method '[]' for nil:NilClass
/.../jobs/twitter_user.rb:19:in 'block in <top (required)>'

看起来问题出在第 19 行,即:

tweets = /profile["']>[\n\t\s]*<strong>([\d.,]+)/.match(response.body)[1].delete('.,').to_i

谁能告诉我发生了什么以及如何解决它?

【问题讨论】:

  • 问题是代码没有以聪明的方式编写。使用正则表达式来解析 XML 或 HTML 是一种等待,除非它的内容由编写代码的人拥有并且该内容不会改变并且这是一项微不足道的任务。更改这三个中的一个,代码破坏的几率会迅速上升。我们需要查看您遇到的 HTML 示例,以便重现问题。 “有关您编写的代码问题的问题必须在问题本身中描述具体问题 - 并包括有效的代码来重现它。有关指导,请参阅 SSCCE.org。”
  • 我认为你是对的。它甚至看起来不像是在他们制作的 webapp 上运行的作业foobugs-dashboard.herokuapp.com/tv

标签: ruby twitter dashing


【解决方案1】:

你的假设是错误的。该程序正在寻找一个名为TWITTER_USERNAME环境变量,它被设置为相关的用户名。如果该变量不存在,则代码将使用 foobugs

如果您宁愿修改代码而不是设置环境变量,请更改

twitter_username = ENV['TWITTER_USERNAME'] || 'foobugs'

twitter_username = 'myusername'

【讨论】:

    【解决方案2】:

    这是未经测试的代码,但它是一个大致的想法,应该如何编写。如果您在原始页面上克隆源代码,您可以根据自己的目的对其进行调整(即修复它):

    require 'nokogiri'
    
    doc = Nokogiri::XML(content)
    
    tweets = doc.at('profile strong').text.delete('.,').to_i
    following = doc.at('following strong').text.delete('.,').to_i
    followers = doc.at('followers strong').text.delete('.,').to_i
    

    以上三行可以简化为:

    tweets, following, followers = %w[profile following followers].map{ |tag|
      doc.at("#{ tag } strong").text.delete(',.').to_i
    }
    

    同样,如果没有可用的 XML/HTML 示例,我将无能为力,但作为惯例,我们(程序员)不应该使用正则表达式来尝试解析 XML 或 HTML。使用这两种类型的文件中的任何一种都可以很容易地打破模式。

    【讨论】:

      【解决方案3】:

      我通过使用 twitter API 来提取相关信息,为自己解决了同样的问题。似乎网页变化太大,无法进行抓取,而且它也可能会在没有通知的情况下再次停止工作,正如许多人已经说过的那样......

      这是我使用的解决方案。

      #### Get your twitter keys & secrets:
      #### https://dev.twitter.com/docs/auth/tokens-devtwittercom
      Twitter.configure do |config|
        config.consumer_key = 'YOUR_CONSUMER_KEY'
        config.consumer_secret = 'YOUR_CONSUMER_SECRET'
        config.oauth_token = 'YOUR_OAUTH_TOKEN'
        config.oauth_token_secret = 'YOUR_OAUTH_SECRET'
      
      end
      
      twitter_username = 'foobugs'
      
      MAX_USER_ATTEMPTS = 10
      user_attempts = 0
      
      SCHEDULER.every '10m', :first_in => 0 do |job|
        begin
          tw_user = Twitter.user("#{twitter_username}")
          if tw_user
              tweets = tw_user.statuses_count
              followers = tw_user.followers_count
              following = tw_user.friends_count
      
              send_event('twitter_user_tweets', current: tweets)
              send_event('twitter_user_followers', current: followers)
              send_event('twitter_user_following', current: following)
      
          end
        rescue Twitter::Error => e
          user_attempts = user_attempts +1
          puts "Twitter error #{e}"
          puts "\e[33mFor the twitter_user widget to work, you need to put in your twitter API keys in the jobs/twitter_user.rb file.\e[0m"
          sleep 5
          retry if(user_attempts < MAX_USER_ATTEMPTS)
        end
      end
      

      【讨论】:

        【解决方案4】:

        我已经通过替换这一行来解决:

        followers = /<strong>([\d.]+)<\/strong> Follower/.match(response.body)[0].delete('.,').to_i
        

        这两个:

        followers_count_metadata = /followers_count&quot;:[\d]+/.match(response.body)
        followers = /[\d]+/.match(followers_count_metadata.to_s).to_s
        

        【讨论】:

          猜你喜欢
          • 2014-11-17
          • 1970-01-01
          • 2011-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-14
          • 1970-01-01
          • 2015-06-19
          相关资源
          最近更新 更多