繁体   English   中英

使用来自代理后面的PHP的urllib2执行python脚本

[英]Execute python script using urllib2 from PHP behind Proxy

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

在命令行上时,我能够在.bashrc中导出代理设置,以允许脚本通过代理退出并发出请求。

因此,脚本确实可以从代理后面运行。

这是问题所在:我需要从网站上的php脚本调用此Python脚本。 我尝试了几种方法来通过使用以下脚本来调用此脚本:exec(),popen(),shell_exec()

我无法获得返回任何结果的脚本。 当尾随/ var / log / httpd / error * *时,我可以看到正在生成的错误:

urllib2.URLError: <urlopen error [Errno 110] Connection timed out>, referer:

这与在.bashrc中设置代理之前收到的错误相同

我已设置suPHP并将其配置为以特定用户身份运行脚本。 我还将所有文件(包括python脚本)设置为该用户所有,还调整了权限,尝试+ x并出于测试目的将其不安全地设置为777。

我可以从网站的同一目录运行一个php脚本,并通过以下简单方法验证Apache是​​否在该用户下运行:

echo exec('whoami');

我还可以使用相同的设置从同一PHP页面执行一个简单的Python脚本,该设置仅打印到stdout,并且我可以将该值返回给网页,因此我知道可以使用此方法执行Python脚本。

在命令行中,我使用与Apache运行时所建立的用户相同的用户身份,并在该帐户中设置代理,但是,从Web页执行脚本时脚本仍然无法正确执行,仍然只能在CLI。

为了测试,我添加了一行代码以Python脚本的形式写入文件,目的是将数据写入需要返回的文件,以为以后可以读取该文件。 我注意到的是,文件的创建是可行的,但是由于urllib2代码超时并且从不写入文件,因此没有数据写入其中。

知道如何使我的PHP脚本执行需要代理访问权限的Python脚本吗?

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

任何帮助是极大的赞赏。

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

proxy = urllib2.ProxyHandler({'http': '127.0.0.1'})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
urllib2.urlopen('http://www.google.com')

令人惊讶的是,你必须这样做,因为明确的文档urlopen说:

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

environment variable properly set in the environment the script runs? 您是否在脚本运行的环境中正确设置了环境变量?


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

您可以尝试将显式代理设置传递给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应该使用您的系统设置进行任何代理处理,但是我想有时候这可能无法按您希望的方式工作。 明确定义设置可能不会受到伤害。 您也可以查看该文档以获取更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM