обрабатывать все ссылки, кроме внешних (ruby + mechanize) - PullRequest
3 голосов
/ 27 апреля 2010

Я хочу обработать все ссылки, кроме внешних со всего веб-сайта. Есть ли простой способ, как определить, что ссылка является внешней, и пропустить ее?

Мой код выглядит так (URL сайта передается через аргумент командной строки)

Я использую механизировать (0.9.3) и ruby ​​1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]

Обратите внимание, что веб-сайт может использовать относительный путь, поэтому хост / домен отсутствует, и это немного усложняет

require 'mechanize'

def process_page(page) 
  puts
  puts page.title
  STDIN.gets
  page.links.each do |link|
process_page($agent.get(link.href))
  end
end

$agent = WWW::Mechanize.new 
$agent.user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4'
process_page($agent.get(ARGV[0]))

Ответы [ 2 ]

7 голосов
/ 27 апреля 2010

URI имеет несколько методов, которые позволяют легко увидеть, просматриваете ли вы локальный URL-адрес или один на другом сайте.

Это небольшая модификация из примера документа URI .route_to ():

require 'uri'

URI.parse('/main.rbx?page=1').host # => nil
URI.parse('main.rbx?page=1').host  # => nil

Внутренние URL не имеют хоста, поэтому я бы проанализировал соответствующие URL и посмотрел, есть ли у них хост. Если нет, то это внутренняя часть сайта.

URL-адрес, указывающий на внешний сайт, вернет значение для хоста, но также и полный URL-адрес для рассматриваемого сайта, поэтому вам нужно сделать еще несколько сообщений.

uri = URI.parse('http://my.example.com')

uri.route_to('http://my.example.com/main.rbx?page=1').host  # => nil
uri.route_to('http://another.com/main.rbx?page=1').host # => "another.com"

Если у него есть хост, посмотрите, соответствует ли этот хост хосту вашего начального URL. Это можно сделать с помощью поиска по подстроке или совпадения с регулярным выражением, но оба из них могут возвращать ложные срабатывания в случае совпадения подстроки.

Вместо этого я бы использовал методы URI, чтобы избежать ложных срабатываний; Используйте route_to (), чтобы попытаться построить относительный путь к URL. Если результат имеет значение .host, то он внешний.

1 голос
/ 27 апреля 2010

Используйте метод ссылки URI:

  page.links.each do |link|
     next unless link.uri.host.match(/(www\.)?thissite\.com/)
     process_page($agent.get(link.href))
  end
...