从 Mathematica 中的 Web 设置用户代理导入
当我使用 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,如 Gecko)Chrome/11.0.696.68 Safari/534.24"
when I connect to my site with Mathermatica (Import["mysite","Data"]
) and look at my Apache log I see: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"
Could I set it to be something like this (when I connects with real browser):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"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
据我所知,您无法更改 Mathematica 中的用户代理字符串。我曾经使用代理服务器(CNTLM)让 Mathematica 与使用 NTLM 身份验证(Mathematica 不支持)的防火墙进行通信。 CNTLM 还允许您设置用户代理字符串。
您可以在 http://cntlm.sourceforge.net/ 找到它。基本上,您将此代理服务器设置为在您自己的计算机上运行,并在 Mathematica 网络设置中设置其端口号和 IP 地址。代理添加用户代理内容并处理 NTLM 身份验证。如果您没有 NTLM 防火墙,则不确定它如何工作。还有其他免费代理可能适合您。
编辑Squid http代理似乎可以做你想做的事。它具有
request_header_replace
配置指令,允许您更改请求标头的内容。As far as I know you can't change the user agent string in Mathematica. I once used a proxy server (CNTLM) to get Mathematica to talk with a firewall which used NTLM authentication (which Mathematica doesn't support). CNTLM also allows you to set the user agent string.
You can find it at http://cntlm.sourceforge.net/. Basically, you set-up this proxy server to run on your own machine and set its port number and ip-address in the Mathematica network settings. The proxy adds user agent stuff and handles the NTLM authentication. Not sure how it works if you don't have a NTLM firewall. There are other free proxies around that might work for you.
EDIT The Squid http proxy seems to do what you want. It has the
request_header_replace
configuration directive which allows you to change the contents of request headers.以下是通过 JLink 使用 Apache HTTP 客户端的方法:
您可以按如下方式使用此函数:
如果需要,您可以将结果提供给
ImportString
:使用更复杂的代码可以使用流式方法,但是除非目标 Web 资源非常大,否则上面采用的基于字符串的方法可能就足够好了。
我在 Mathematica 7 和 8 中尝试了这段代码,我希望它也能在 v6 中工作。请注意,不能保证 Mathematica 在未来版本中始终包含 Apache HTTP 客户端。
工作原理
尽管该解决方案是用 Mathematica 表达的,但它本质上是用 Java 实现的。 Mathematica 附带了内置的 Java 运行时环境,Mathematica 和 Java 之间的桥梁是一个名为 JLink。
正如此类跨技术解决方案的典型情况一样,即使代码不多,也存在相当大的复杂性。详细讨论代码如何工作超出了本答案的范围,但将强调一些项目作为进一步阅读的建议。
该代码使用 Apache HTTP 客户端。之所以选择这个 Java 库,是因为它是作为标准 Mathematica 发行版中未公开的一部分提供的,而且它也恰好是
Import
似乎在内部使用的库。urlString
的整个主体被包裹在JavaBlock
中。这确保了通过协调 Java 和 Mathematica 内存管理器的活动来正确释放在操作过程中创建的任何 Java 对象。JavaNew
用于创建相关的 Apache HTTP 客户端对象、HttpClient
和GetMethod
。像http.getParams()
这样的 Java 表达式在 JLink 中表示为http@getParams[]
。 Java 类和方法记录在 Apache HTTP 客户端文档中。MakeJavaObject
的使用有些不寻常。在这种情况下,这是必需的,因为 Mathematica 字符串作为参数传递,其中需要 JavaObject
。如果需要 JavaString
,JLink 将自动创建一个。但当需要Object
时,JLink 无法做出此推断,因此使用MakeJavaObject
来给 JLink 提示。URLTools 怎么样?
顺便说一句,我尝试回答这个问题的第一件事是使用
Utilities`URLTools`FetchURL
。它看起来非常有前途,因为它采用了一个名为“RequestHeaderFields”的选项。唉,这不起作用,因为该函数的当前实现仅对 HTTP POST 动词使用该选项,而不是 GET。也许 Mathematica 的某些未来版本将支持 GET 选项。Here is a way to use the Apache HTTP client through JLink:
You can use this function as follows:
You can feed the result to
ImportString
if desired:A streaming approach would be possible using more elaborate code, but the string-based approach taken above is probably good enough unless the target web resource is very large.
I tried this code in Mathematica 7 and 8, and I expect that it works in v6 as well. Beware that there is no guarantee that Mathematica will always include the Apache HTTP client in future releases.
How It Works
Despite being expressed in Mathematica, the solution is essentially implemented in Java. Mathematica ships with a Java runtime environment built-in and the bridge between Mathematica and Java is a component called JLink.
As is typical of such cross-technology solutions, there is a fair amount of complexity even when there is not much code. It is beyond the scope of this answer to discuss how the code works in detail, but a few items will be emphasized as suggestions for further reading.
The code uses the Apache HTTP client. This Java library was chosen because it ships as an unadvertised part of the standard Mathematica distribution -- and it also happens to be the one that
Import
appears to use internally.The whole body of
urlString
is wrapped inJavaBlock
. This ensures that any Java objects that are created over the course of operation are properly released by co-ordinating the activities of the Java and Mathematica memory managers.JavaNew
is used to create the relevant Apache HTTP client objects,HttpClient
andGetMethod
. Java expressions likehttp.getParams()
are expressed in JLink ashttp@getParams[]
. The Java classes and methods are documented in the Apache HTTP client documentation.The use of
MakeJavaObject
is somewhat unusual. It is required in this case as a Mathematica string is being passed as an argument where a JavaObject
is expected. If a JavaString
was expected, JLink would automatically create one. But JLink is unable to make this inference whenObject
is expected, soMakeJavaObject
is used to give JLink a hint.What about URLTools?
Incidentally, the first thing I tried to answer this question was to use
Utilities`URLTools`FetchURL
. It looked very promising since it takes an option called"RequestHeaderFields"
. Alas, this did not work because the present implementation of that function uses that option only for HTTP POST verbs -- not GET. Perhaps some future version of Mathematica will support the option for GET.我非常懒,curl 比 J/Link 更灵活,代码更少,而且没有对象管理问题。这是将数据 (userPass) 发布到 url 并以 JSON 格式检索结果的示例。
我将这种东西隔离在一个不纯的函数中(除非它是纯的),所以我知道它被污染了,但任何网络访问都是这样的。
因为我使用管道,所以 MMA 无法推断文件的类型。 ref/Import 提到 « Import["!prog","format"] 从管道导入数据. » 和 « 文件的格式默认是从其名称中的文件扩展名推断出来的,或者是通过 FileFormat 从其内容推断出来的。 » 因此,需要指定“CSV”、“JSON”等作为格式参数。否则你会看到一些奇怪的结果。
来自curl 和 libcurl 欢迎页面。
I'm extremely lazy and curl is more flexible in less code than J/Link, without the object management issues. This is an example of posting data (userPass) to a url and retrieving the result in JSON format.
I isolate this kind of thing in an impure function (unless it is pure) so I know it's tainted, but any web access is that way.
Because I use a pipe, MMA cannot deduce the type of file. ref/Import mentions that « Import["!prog","format"] imports data from a pipe. » and « The format of a file is by default deduced from the file extension in its name, or by FileFormat from its contents. » As a result, it is necessary to specify "CSV", "JSON", etc. as the format parameter. You'll see some strange results otherwise.
From the curl and libcurl welcome page.
Mathematica 通过用户指定的代理服务器进行所有互联网连接。如果正如 Sjoerd 所建议的那样,设置一个工作量太大,您可能需要考虑用 C/C++ 编写调用,然后从 Mathematica 中调用它。我毫不怀疑有很多 C 库可以用几行代码完成您想要的事情。
有关在 Mathematica 中调用 C 代码的信息,请参阅 C 语言接口文档
Mathematica does all of its internet connectivity through a user specified proxy server. If, as Sjoerd suggested, setting one up is too much work, you might want to consider writing the call in C/C++, and then calling that from Mathematica. I don't doubt there are plenty of C libraries that do what you want in a few lines of code.
For calling C code within Mathematica, see the C Language Interface documentation
Mathematica 9 具有新的 URLFetch 函数。它有 UserAgent 选项。
Mathematica 9 has the new URLFetch function. It has the option UserAgent.
您还可以使用 J/Link 发出 Web 请求或在命令行上调用curl 或wget。
You can also use J/Link to make your web requests or call curl or wget on the command line.