когда я подключаюсь к своему сайту с помощью Mathermatica (Import["mysite","Data"]
) и просматриваю свой журнал Apache, я вижу: 99.XXX.XXX.XXX - - [22/May/2011:19:36:28 +0200] "GET / HTTP/1.1" 200 6268 "-" "Mathematica/8.0.1.0.0 PM/1.3.1"
Могу ли я установить его как нечто подобное (когда я подключаюсь к реальному браузеру): 99.XXX.XXX.XXX - - [22/May/2011:19:46:17 +0200] "GET /favicon.ico HTTP/1.1" 404 183 "-" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.68 Safari/534.24"
Импорт из веб-агента пользователя в Mathematica
Ответ 1
Mathematica 9 имеет новую функцию URLFetch. У него есть опция UserAgent.
Ответ 2
Насколько я знаю, вы не можете изменить строку пользовательского агента в Mathematica. Я однажды использовал прокси-сервер (CNTLM), чтобы заставить Mathematica поговорить с брандмауэром, который использовал аутентификацию NTLM (что Mathematica не поддерживает). CNTLM также позволяет вам установить строку пользовательского агента.
Вы можете найти его на http://cntlm.sourceforge.net/. В основном, вы настроили этот прокси-сервер для запуска на своем собственном компьютере и задали его номер порта и ip-адрес в сетевых настройках Mathematica. Прокси-сервер добавляет материал агента пользователя и обрабатывает аутентификацию NTLM. Не знаете, как это работает, если у вас нет брандмауэра NTLM. Существуют и другие бесплатные прокси, которые могут работать для вас.
EDIT Squid http proxy, похоже, делает то, что вы хотите. Он имеет директиву конфигурации request_header_replace
, которая позволяет изменять содержимое заголовков запросов.
Ответ 3
Вот пример использования HTTP-клиента Apache через JLink:
Needs["JLink`"]
[email protected]
urlString[userAgent_String, url_String] :=
[email protected][{http, get}
, http = JavaNew["org.apache.commons.httpclient.HttpClient"]
; [email protected][]@setParameter["http.useragent", [email protected]]
; get = JavaNew["org.apache.commons.httpclient.methods.GetMethod", url]
; [email protected][get]
; [email protected][]
]
Вы можете использовать эту функцию следующим образом:
$userAgent =
"Mozilla/5.0 (X11;Linux i686) AppleWebKit/534.24 (KHTML,like Gecko) Chrome/11.0.696.68 Safari/534.24";
urlString[$userAgent, "http://www.htttools.com:8080/"]
При желании вы можете подать результат ImportString
:
ImportString[urlString[$userAgent, "mysite"], "Data"]
Поток будет возможен с использованием более сложного кода, но основанный на строках подход, вероятно, достаточно хорош, если целевой веб-ресурс очень большой.
Я пробовал этот код в Mathematica 7 и 8, и я ожидаю, что он будет работать и в v6. Помните, что нет гарантии, что Mathematica всегда будет включать HTTP-клиент Apache в будущих выпусках.
Как это работает
Несмотря на то, что оно выражено в Mathematica, решение по существу реализовано на Java. Mathematica поставляется со встроенной средой выполнения Java, а мост между Mathematica и Java - это компонент, называемый JLink.
Как типично для таких кросс-технологических решений, существует довольно много сложностей, даже если кода не так много. Выходит за рамки этого ответа, чтобы обсудить, как работает код в деталях, но несколько пунктов будут выделены в качестве предложений для дальнейшего чтения.
В коде используется Apache HTTP client. Эта библиотека Java была выбрана потому, что она поставляется как неотправленная часть стандартного дистрибутива Mathematica, а также, по-видимому, она используется Import
.
Все тело urlString
завернуто в JavaBlock
. Это гарантирует, что любые объекты Java, созданные во время работы, будут правильно выпущены путем координации действий менеджеров памяти Java и Mathematica.
JavaNew
используется для создания соответствующих клиентских объектов Apache HTTP, HttpClient
и GetMethod
. Явные выражения, такие как http.getParams()
, выражаются в JLink как [email protected][]
. Классы и методы Java задокументированы в документации клиента HTTP Apache.
Использование MakeJavaObject
несколько необычно. В этом случае требуется, чтобы строка Mathematica передавалась как аргумент, где ожидается Java Object
. Если ожидается Java String
, JLink автоматически создаст его. Но JLink не может сделать этот вывод, когда ожидается Object
, поэтому MakeJavaObject
используется, чтобы дать подсказке JLink.
Как насчет URLTools?
Кстати, первое, на что я попытался ответить на этот вопрос, было использовать Utilities`URLTools`FetchURL
. Это выглядело очень многообещающим, так как он использует опцию "RequestHeaderFields"
. Увы, это не сработало, потому что нынешняя реализация этой функции использует этот параметр только для HTTP POST-глаголов - не GET. Возможно, какая-то будущая версия Mathematica будет поддерживать опцию GET.
Ответ 4
Я очень ленив, и завиток более гибкий в меньшем количестве кода, чем J/Link, без проблем управления объектами. Это пример публикации данных (userPass) в URL-адрес и получение результата в формате JSON.
Import["!curl -A Mozilla/4.0 --data " <> userPass <> " " <> url, "JSON"]
Я изолирую эту вещь в нечистой функции (если только она не чиста), поэтому я знаю, что она испорчена, но любой доступ к сети такой.
Поскольку я использую канал, MMA не может выводить тип файла. ref/Import упоминает, что "Import ["! prog "," format "] импортирует данные из трубы." И "Формат файла по умолчанию выводится из расширения файла в его имени или FileFormat из его содержимого." В результате в качестве параметра формата необходимо указать" CSV "," JSON "и т.д. В противном случае вы увидите некоторые странные результаты.
curl - это инструмент командной строки для передачи данных с синтаксисом URL-адресов, поддерживающий DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET и TFTP. curl поддерживает SSL-сертификаты, HTTP POST, HTTP PUT, FTP-загрузку, загрузку на основе HTTP-форм, прокси-серверы, файлы cookie, аутентификацию пользователя и пароля (Basic, Digest, NTLM, Negotiate, kerberos...), возобновление передачи файлов, прокси-туннелирование и загрузка других полезных трюков.
Ответ 5
Mathematica выполняет все свои интернет-подключения через указанный прокси-сервер пользователя. Если, как предложил Сьёрд, установка слишком большой работы, вы можете захотеть написать вызов в C/С++, а затем вызвать это из Mathematica. Я не сомневаюсь, что существует множество библиотек C, которые делают то, что вы хотите, в нескольких строках кода.
Для вызова кода C в Mathematica см. Документация по языку интерфейса C
Ответ 6
Вы также можете использовать J/Link для создания своих веб-запросов или вызова curl или wget в командной строке.