【问题标题】:Continuous input as in wikipedia维基百科中的连续输入
【发布时间】:2018-03-26 02:40:49
【问题描述】:

所以我正在学习 ruby​​ 并想从维基百科上报废。

require "rubygems"
require "json"
require 'restclient'
require 'crack'
require 'io/console'


parse = ""
5.times{
    inp = STDIN.getch
    parse += inp
    url="http://en.wikipedia.org/w/api.php?action=opensearch&search=#{parse}&namespace=0"

    data= Crack::JSON.parse(RestClient.get(url))
    puts data[1]
}

因此,我编写的这段代码从用户那里获取了 5 次输入,将输入连接起来,并从 wiki 搜索解析 JSON 中抓取输出。但我希望输入处于流中,而不是用户点击一个等待输出的字符并再次点击下一个字符。相反,我希望它输入几个字符而不按Enter,如果有一个暂停说1秒或更长时间,它应该开始抓取并给出输出。

背后的一个主要原因是允许用户删除他写的一些文本或添加更多字母,并且脚本可以再次跟踪输入字段中留下的任何内容在初始暂停后显示输出。


基本上我希望它就像 wiki 本身一样。随时可以进入搜索组修改,总有新的输出等待。

编辑:

require "rubygems"
require "json"
require 'restclient'
require 'crack'
require 'io/console'

parse=""
ch=""
t2 =Thread.new do
    loop do
        temp=STDIN.getch
        parse+=temp
    end
end

t=Thread.new do
    loop do
        if parse!=ch
            sleep 1
            url="http://en.wikipedia.org/w/api.php?action=opensearch&search=#{parse}&namespace=0"
            data = Crack::JSON.parse(RestClient.get(url))
            #puts parse
            puts data[1]
            ch=parse
        end
    end
end

t.join
t2.join

这很好用,但是当用户按下回车键时如何结束线程。

【问题讨论】:

  • 为什么要打印数据[1]?
  • @Sankalp data[0] 正在打印 JSON 的第一个“部分”,而 data[1] 有第二部分,依此类推。 Data[1] 仅具有特定名称,因此我打印了 data[1]
  • 使用线程——主线程处理用户输入(循环),“wiki”线程获取相应的页面。
  • @Stefan 我使用线程并得到了我想要的。唯一的问题是,当用户按 Enter 键时,我无法弄清楚如何停止/杀死线程。我当然可以检查是否为temp=='\n',但如果是true,则如何结束线程。请检查编辑。
  • 您只需要一个额外的线程,而不是两个。输入可以在你的 main 线程中处理。只需loop,直到用户点击返回(或转义或其他),然后break 退出循环,kill 另一个线程。

标签: ruby input web-scraping wikipedia


【解决方案1】:

getch 实际上需要两个(文档不足)关键字参数,它们完全符合您的要求

# wait for 0 characters, timeout after 2 seconds
char = STDIN.getch min:0, time:2

如果用户在两秒内没有按任何键,char 将变为nil。您可以在循环中调用它并使用该结果作为启动抓取的触发器。

【讨论】:

  • 这绝对适用于输入部分,但请检查编辑。我使用线程,它更方便。我只是无法弄清楚当用户点击 Enter 时如何退出线程,即当temp=="\n"
  • @Rishav 刚刚跳出循环。如果temp 是换行符,则设置一些全局done=true,然后将break if done 添加到您的两个循环中。
【解决方案2】:
require "rubygems"
require "json"
require 'restclient'
require 'crack'
require 'io/console'

parse=""
ch=""
done=false
t2 =Thread.new do
    loop do
        temp=STDIN.getch
        if temp=="\n"
            done=true
            break
        end
        parse+=temp
    end
end

t=Thread.new do
    loop do
        if done==true
            break
        end
        if parse!=ch
            sleep 1
            url="http://en.wikipedia.org/w/api.php?action=opensearch&search=#{parse}&namespace=0"
            data = Crack::JSON.parse(RestClient.get(url))
            #puts parse
            puts data[1]
            ch=parse
        end
    end
end

t.join
t2.join

puts "Thanks!"
gets

【讨论】:

    【解决方案3】:

    使用.chomp,它不仅会读取\n,还会读取空格。也只需要 1 个线程,而不是 2 个。

    require "json"
    require 'restclient'
    require 'crack'
    require 'io/console'
    
    parse=""
    ch=""
    done=false
    
    t2 =Thread.new do
        loop do
            temp=STDIN.getch.chomp
            if temp==""
                done=true
                break
            end
            parse+=temp
        end
    end
    
    while !done
        if parse!=ch
            sleep 1
            url="http://en.wikipedia.org/w/api.php?action=opensearch&search=#{parse}&namespace=0"
            data = Crack::JSON.parse(RestClient.get(url))
            puts data[1]
            ch=parse
        end
    end
    t2.join
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-26
      • 2019-04-18
      • 2019-05-24
      • 1970-01-01
      • 2011-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多