在代理后使用PHP中的urllib2执行python脚本

在代理后使用PHP中的urllib2执行python脚本,php,python,apache,urllib2,Php,Python,Apache,Urllib2,我有一个Python脚本,它使用urllib2从外部站点检索数据。 我在一个需要代理身份验证的公司网络上 在命令行中,我可以导出.bashrc中的代理设置,以允许脚本通过代理退出并发出请求 因此,脚本确实在代理后面工作 问题是: 我需要从网站上的php脚本调用这个Python脚本。 我尝试了几种方法通过调用脚本来实现这一点: exec(),popen(),shell_exec() 我无法让脚本返回任何结果。 跟踪时/var/log/httpd/error** 我可以看到正在生成的错误: urll

我有一个Python脚本,它使用urllib2从外部站点检索数据。 我在一个需要代理身份验证的公司网络上

在命令行中,我可以导出.bashrc中的代理设置,以允许脚本通过代理退出并发出请求

因此,脚本确实在代理后面工作

问题是: 我需要从网站上的php脚本调用这个Python脚本。 我尝试了几种方法通过调用脚本来实现这一点: exec(),popen(),shell_exec()

我无法让脚本返回任何结果。 跟踪时/var/log/httpd/error** 我可以看到正在生成的错误:

urllib2.URLError: <urlopen error [Errno 110] Connection timed out>, referer:
我还可以从同一个PHP页面执行一个简单的Python脚本,使用只打印到stdout的相同设置,并且我可以将该值返回到网页,因此我知道我可以使用此方法执行Python脚本

在命令行中时,我会将脚本发送给与Apache运行时所使用的用户相同的用户,并在该帐户中设置代理,但从网页执行脚本时,脚本仍然无法正确执行,仍然只能在CLI中运行

为了测试,我在Python脚本中添加了一行代码来写入一个文件,目的是将需要返回的数据写入该文件,并认为可以在以后读取该文件。 我注意到的是,文件的创建工作正常,但由于urllib2代码超时且从未写入文件,因此不会向其中写入任何数据

你知道如何让我的PHP脚本执行这个需要代理访问的Python脚本吗

我是否需要显式地告诉urllib2使用代理? 我正在使用的urllib2例程是Python模块的一部分,该模块被编码为只使用操作系统的代理设置,而且,我知道它可以工作,因为我可以在Apache用户的CLI下执行它


非常感谢您提供的任何帮助。

您可以尝试将显式代理设置传递到Python脚本,看看这是否为您解决了问题。我最近编写了一个脚本,允许您使用命令行参数设置代理设置,这在这种情况下可能很有用。脚本的重要部分如下所示:

# Import the required libraries
from urllib import urlencode
from urllib2 import Request, urlopen, URLError, ProxyHandler, build_opener, install_opener
import argparse

# Set up our argument parser
parser = argparse.ArgumentParser(description='Does stuff through a proxy')
parser.add_argument('webAddr', type=str, help='Web address of target server')
parser.add_argument('--proxServ', metavar='SERV', type=str, help='Web address of proxy server, i.e. http://proxy.server.com:80')
parser.add_argument('--proxType', metavar='TYPE', type=str, default='http', help='Type of proxy server, i.e. http')

# Get the arguments from the parser
args = parser.parse_args()

# Define data to pass to server (could generate this from arguments as well)
values = {'name': 'data'}   # generate data to pass to server

# Define proxy settings if proxy server is input.
if args.proxServ:       # set up the proxy server support
    proxySupport = ProxyHandler({args.proxType: args.proxServ})
    opener = build_opener(proxySupport)
    install_opener(opener)

# Set up the data object
data = urlencode(values)
data = data.encode('utf-8')

# Send request to the server and receive response, with error handling!
try:
    req = Request(args.webAddr, data)

    # Read the response and print to a file
    response = urlopen(req)
    print response.read()

except URLError, e:
    if hasattr(e, 'reason'):    # URL error case
        # a tuple containing error code and text error message
        print 'Error: Failed to reach a server.'
        print 'Reason: ', e.reason
    elif hasattr(e, 'code'):    # HTTP error case
        # HTTP error code, see section 10 of RFC 2616 for details
        print 'Error: The server could not fulfill the request.'
        print 'Error code: ', e.code

urllib2
应该使用您的系统设置进行任何代理处理,但我想有时这可能无法按您希望的方式工作。明确定义设置可能不会有什么坏处。您也可以签出以获取更多信息。

要通知urllib2使用代理,您可以使用:

令人惊讶的是,你必须明确地这样做,因为美国国防部说:

此外,如果检测到代理设置(例如,当设置了*\u代理环境变量(如http\u proxy)时),则默认安装ProxyHandler,并确保通过代理处理请求

您是否在脚本运行的环境中正确设置了http_代理环境变量



您将在前面的问题中找到有关如何将代理与urllib2一起使用的更多信息:

Yes。假设我的apache用户名为“bob”。我已经访问了bob,并为“bob”设置了http_代理,即accounts.bashrc。我还可以在登录到“bob”时执行脚本。urllib2确实检测到此代理设置并执行,但它仅在通过命令行执行时才以这种方式工作。@luskbo不确定是否理解。但是通常CGI脚本使用一组非常有限的环境变量运行。可能http_代理未在该上下文中设置?@luskbo对于Apache,有一个
SetEnv
指令控制CGI的环境变量。首先看一看,最终解决它的是显式设置代理值。不确定为什么urllib2没有像预期的那样接受OS集值,但是关于从php执行它的一些事情打破了这一点。我的SetEvn中既有指向php的路径,也有指向python的路径,所以我不确定这是怎么回事。SetEnv PATH/usr/bin:/usr/local/bin:/bin:/usr/bin/python:/usr/bin/php但是在这种情况下显式设置代理确实有效,所以谢谢!!!我将对此进行一次尝试,并对结果进行评论。非常感谢。太棒了,很高兴听到它有帮助!
# Import the required libraries
from urllib import urlencode
from urllib2 import Request, urlopen, URLError, ProxyHandler, build_opener, install_opener
import argparse

# Set up our argument parser
parser = argparse.ArgumentParser(description='Does stuff through a proxy')
parser.add_argument('webAddr', type=str, help='Web address of target server')
parser.add_argument('--proxServ', metavar='SERV', type=str, help='Web address of proxy server, i.e. http://proxy.server.com:80')
parser.add_argument('--proxType', metavar='TYPE', type=str, default='http', help='Type of proxy server, i.e. http')

# Get the arguments from the parser
args = parser.parse_args()

# Define data to pass to server (could generate this from arguments as well)
values = {'name': 'data'}   # generate data to pass to server

# Define proxy settings if proxy server is input.
if args.proxServ:       # set up the proxy server support
    proxySupport = ProxyHandler({args.proxType: args.proxServ})
    opener = build_opener(proxySupport)
    install_opener(opener)

# Set up the data object
data = urlencode(values)
data = data.encode('utf-8')

# Send request to the server and receive response, with error handling!
try:
    req = Request(args.webAddr, data)

    # Read the response and print to a file
    response = urlopen(req)
    print response.read()

except URLError, e:
    if hasattr(e, 'reason'):    # URL error case
        # a tuple containing error code and text error message
        print 'Error: Failed to reach a server.'
        print 'Reason: ', e.reason
    elif hasattr(e, 'code'):    # HTTP error case
        # HTTP error code, see section 10 of RFC 2616 for details
        print 'Error: The server could not fulfill the request.'
        print 'Error code: ', e.code
proxy = urllib2.ProxyHandler({'http': '127.0.0.1'})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
urllib2.urlopen('http://www.google.com')