使用Ruby程序实现web信息抓取的教程

2019-09-25 09:45:09王冬梅

Yelp 提供了一个具有出色文档的 API,以及数据描述、示例、错误处理等。尽管 Yelp API 很有用,但它的使用有一定的限制。作为软件原始开发人员,您每天最多可执行 100 次 API 调用,出于测试用途可执行 1,000 次调用。如果您的应用程序满足 Yelp 的显示需求,每天可执行 10,000 次调用(也可能执行更多次)。

包含一个简单 mashup 的域位置

下一个示例将两段源代码连接起来,以生成信息。在本例中,您要将一个 Web 域名转换为它的一般地理位置。清单 8 中的 Ruby 脚本使用 Linux? host 命令和 OpenCrypt IP Location API Service 来检索位置信息。
清单 8. 检索 Web 域的位置信息

#!/usr/bin/env ruby
require 'net/http'

aggr = ""
key = 'your api key here'

# Get the IP address for the domain using the 'host' command
IO.popen("host #{ARGV[0]}") { | line |
 until line.eof?
  aggr += line.gets
 end
}

# Find the IP address in the response from the 'host' command
pattern = /d{1,3}.d{1,3}.d{1,3}.d{1,3}$/
if m = pattern.match(aggr)
  uri = "http://api.opencrypt.com/ip/?IP=#{m[0]}&key=#{key}"
  resp = Net::HTTP.get_response(URI.parse(uri))
  puts resp.body
end

在清单 8 中,您首先使用本地的 host 命令将域名转换为 IP 地址。(host 命令本身使用一个内部 API 和 DNS 解析将域名解析为 IP 地址。)您使用一个简单的正则表达式(和 match 方法)从 host 命令输出中解析 IP 地址。有了 IP 地址,就可使用 OpenCrypt 上的 IP 位置服务来检索一般地理位置信息。OpenCrypt API 允许您执行最多 50,000 次免费 API 调用。

OpenCrypt API 调用很简单:您构造的 URL 包含您要定位的 IP 地址和 OpenCrypt 注册过程提供给您的密钥。HTTP 响应正文包含 IP 地址、国家代码和国家名称。

清单 9 中的控制台会话显示了两个示例域名的输出。
清单 9. 使用简单的域位置脚本

$ ./where.rb www.baynet.ne.jp
IP=111.68.239.125
CC=JP
CN=Japan
$ ./where.rb www.pravda.ru
IP=212.76.137.2
CC=RU
CN=Russian Federation
$

Google API 查询

Web API 方面一个无可争辩的优胜者是 Google。Google 拥有如此多的 API,以至于它提供了另一个 API 来查询它们。通过 Google API Discovery Service,您可列出 Google 提供的可用 API 并提取它们的元数据。尽管与大部分 Google API 的交互需要进行身份验证,但您可通过一个安全套接字连接访问查询 API。出于此原因,清单 10 使用 Ruby 的 https 类来构造与安全端口的连接。已定义的 URL 指定了 REST 请求,而且响应采用了 JSON 编码。迭代响应并发出一小部分首选的 API 数据。
清单 10. 使用 Google API Discovery Service (gdir.rb) 列出 Google API

#!/usr/bin/ruby
require 'rubygems'
require 'net/https'
require 'json'

url = 'https://www.googleapis.com/discovery/v1/apis'

uri = URI.parse(url)

# Set up a connection to the Google API Service
http = Net::HTTP.new( uri.host, 443 )
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

# Connect to the service
req = Net::HTTP::Get.new(uri.request_uri)
resp = http.request(req)

# Get the JSON representation
jresp = JSON.parse(resp.body)

# Iterate through the API List
jresp['items'].each do | item |
 if item['preferred'] == true
  name = item['name']
  title = item['title']
  link = item['discoveryLink']
  printf("%-17s %-34s %-20sn", name, title, link)
 end
end