9 июля 2011 г.

поиск гиперсылок регулярными выражениями или поиск значения атрибута html тега

Для автоматического составителя robots.txt написал регулярное выражение которая выдирает гипперссылки из html страничек (атрибут href из тега  )
Возможно кому-то будет полезным.
Код парсера с пояснением:
/<\s*a#Тег Гиперссылки
 (?:\s+#название аттрибутов и их значения одной строкой не сохраняем
  (?:href\s*=\s*#Выискиваем атрибут хранящий url
   (?:# возможны три варианта записи url в Гиперссылки
    "([^"^']*)"|# "ww.tetrapolis.ru"
    '([^'^']*)'|# 'www.tetrapolis.ru'
    ([\w\d\.=\-_\,\?\/:#]+)# www.tetrapolis.ru, в этом выражении по возможности указаны все возможные символы -
# альтернатива [\S]+ здесь не подходит так как не остановится у ">"
   )
  |\w+\s*=\s*# Обрабатываем все остальные аттрибуты сохранять бессмысленно так как сохраняется значение последнего аттрибута
   (?:
   "[^'^"]*"|# значение аттрибута html тега в двойных кавычках
   '[^'^"]*'|# значение аттрибута html тега в одинарных кавычках
   [\S]+)# записанный без кавычек - это значение не сохраняем поэтому о достоваерности значения можно не беспокоится
  |\w+)#аттрибут гипперссылки без значения (а вдруг такой будет)
 )+# подразумеваем что в гипперссылке как минимум один аттрибут (иначе он нам не нужен)
\s*>/i# ищем без учета регистра
Небольшой пример на ruby использующий этот парсер:

require 'net/http'
require 'uri'
require 'ping'

class RopotsKiller
 def initialize(url_str,proxy_ip_str, proxy_port_int)
  @url=URI.parse(url_str)
  @proxy_addr=proxy_ip_str
  @proxy_port=proxy_port_int
 end
 def internet_connection?
  Ping.pingecho @url.host, 1, 80
 end
 def start
  # если инет через прокси то использыем прокси
  str = ((self.internet_connection?) ?
  (Net::HTTP):
  (Net::HTTP::Proxy(@proxy_addr, @proxy_port))).start(@url.host, @url.port)   
                {|http|
   http.get('/index.php').body
   }
  str #возвращаем код страницы
 end
 
end
rk = RopotsKiller.new("http://www.tetrapolis.ru/index.php","192.168.255.6",8080)
text=rk.start
pattern=/<\s*a(?:\s+(?:href\s*=\s*(?:"([^"^']*)"|'([^'^"]*)'|([\w\d\.=\-_\,\?\/:#]+))|\w+\s*=\s*(?:"[^"^']*"|'[^'^"]*'|[\S]+)|\w+))+\s*>/i
i=0
text.scan(pattern){ |match|
 p match
 i=i+1
}
puts "Length: #{i}"


Комментариев нет:

Отправить комментарий