Apache Nutch 2.3.1 Fetcher дает исключение Invalid uri

Я настроил Apache Nutch 2.3.1 с экосистемой Hadoop. Я должен получить несколько веб-сайтов, написанных на арабском языке. Nutch дает исключение для нескольких URL во время выборки. Ниже приведен пример исключения

java.lang.IllegalArgumentException: Invalid uri 'http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html': escaped absolute path not valid
    at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222)
    at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)
    at org.apache.nutch.protocol.httpclient.HttpResponse.<init>(HttpResponse.java:77)
    at org.apache.nutch.protocol.httpclient.Http.getResponse(Http.java:173)
    at org.apache.nutch.protocol.http.api.HttpBase.getProtocolOutput(HttpBase.java:245)
    at org.apache.nutch.fetcher.FetcherReducer$FetcherThread.run(FetcherReducer.java:564)

1 ответ

Решение

Я смог воспроизвести эту проблему даже на ветке 1.x. Проблема в том, что класс Java URI, который используется клиентской библиотекой Apache HTTP для внутреннего использования, не поддерживает неэкранированные символы UTF-8:

Из документации JavaDoc для java.net.URI:

Категории персонажей

RFC 2396 точно определяет, какие символы разрешены в различных компонентах ссылки на URI. Следующие категории, большинство из которых взяты из этой спецификации, используются ниже для описания этих ограничений:

  • альфа Буквенные символы US-ASCII, от 'A' до 'Z' и от 'a' до 'z'
  • цифра Десятичные знаки US-ASCII, от 0 до 9
  • alphanum Все буквенные и цифровые символы не зарезервированы Все буквенные символы вместе с символами в строке "_-!. ~ '() *"
  • punct Символы в строке ",;:$&+="
  • Зарезервированы все знаки пунктуации вместе с символами в строке "?/[]@"
  • экранированные экранированные октеты, то есть триплеты, состоящие из символа процента ('%'), за которым следуют две шестнадцатеричные цифры ('0'-'9', 'A'-'F' и 'a'-'f')
  • другие символы Unicode, которые не входят в набор символов US-ASCII, не являются управляющими символами (в соответствии с Character.isISOControl метод), и не являются пробелами (в соответствии с Character.isSpaceChar метод) (Отклонение от RFC 2396, которое ограничено US-ASCII)

Набор всех допустимых символов URI состоит из незарезервированных, зарезервированных, экранированных и других символов.

Правильно экранированный URL будет выглядеть так:

http://agahi.safirak.com/ads/850/%D9%BE%DB%8C%DA%86-%D8%A8%D9%86%D8%AF-%D8%A8%D8%A7%D8%AF%DB%8C-%D9%87%D9%81%D8%AA%DB%8C%D8%B1%DB%8C-1800-%D8%AF%D9%88%D8%B1-%D8%A8%D8%A7%D8%AF%DB%8C-%D8%AC%DB%8C%D8%B3%D9%88%D9%86.html

На самом деле, если вы откроете пример URL в Chrome, а затем скопируете URL из адресной строки, вы получите экранированное представление. Не стесняйтесь открыть вопрос для этого (в противном случае я сделаю это). В то же время вы можете попытаться использовать protocol-http плагин, который не использует HTTP-клиент Apache. Я проверил локально, и parsechecker работает нормально:

➜  local (master) ✗ bin/nutch parsechecker "http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html"
fetching: http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html
robots.txt whitelist not configured.
parsing: http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html
contentType: text/html
signature: 048b390ab07464f5d61ae09646253529
---------
Url
---------------

http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html
---------
ParseData
---------

Version: 5
Status: success(1,0)
Title: پیچ بند بادی هفتیری 1800 دور بادی جیسون-نیازمندی سفیرک
Outlinks: 76
outlink: toUrl: http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html anchor: 
outlink: toUrl: http://agahi.safirak.com/assets/fonts/font-awesome/css/font-awesome.min.css anchor: 
outlink: toUrl: http://agahi.safirak.com/assets/css/bootstrap.css anchor:
...
Другие вопросы по тегам