什么导致了“urlopen error [Errno 13] Permission denied”错误?

3

我正在尝试在Centos7服务器上编写一个Python(版本2.7.5)CGI脚本。我的脚本试图从Librivox网页下载数据,例如...https://librivox.org/selections-from-battle-pieces-and-aspects-of-the-war-by-herman-melville/,但是我的脚本因此出现错误:

<class 'urllib2.URLError'>: <urlopen error [Errno 13] Permission denied> 
      args = (error(13, 'Permission denied'),) 
      errno = None 
      filename = None 
      message = '' 
      reason = error(13, 'Permission denied') 
      strerror = None

我已经关闭了iptables,现在可以执行像`wget -O- https://librivox.org/selections-from-battle-pieces-and-aspects-of-the-war-by-herman-melville/`这样的操作而没有错误。下面是出现错误的代码片段:

def output_html ( url, appname, doobb ):
        print "url is %s<br>" % url
        soup = BeautifulSoup(urllib2.urlopen( url ).read())

更新:感谢 Paul 和 Alecxe,我已经更新了代码如下:
def output_html ( url, appname, doobb ):
        #hdr = {'User-Agent':'Mozilla/5.0'}
        #print "url is %s<br>" % url
        #req = url2lib2.Request(url, headers=hdr)
        # soup = BeautifulSoup(urllib2.urlopen( url ).read())
        headers = {'User-Agent':'Mozilla/5.0'}
        # headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36'}
        response = requests.get( url, headers=headers)

        soup = BeautifulSoup(response.content)

......当我这样做时,出现了稍微不同的错误信息。

response = requests.get( url, headers=headers)

... gets called ...

<class 'requests.exceptions.ConnectionError'>: ('Connection aborted.', error(13, 'Permission denied')) 
      args = (ProtocolError('Connection aborted.', error(13, 'Permission denied')),) 
      errno = None 
      filename = None 
      message = ProtocolError('Connection aborted.', error(13, 'Permission denied')) 
      request = <PreparedRequest [GET]> 
      response = None 
      strerror = None

有趣的是,我写了一个命令行版本的这个脚本,它能够很好地运行,并且看起来像这样...

def output_html ( url ):
        soup = BeautifulSoup(urllib2.urlopen( url ).read())

非常奇怪,你觉得呢?

更新: 这个问题可能已经在这里有答案了: urllib2.HTTPError: HTTP Error 403: Forbidden 2 answers

不,它们并没有回答这个问题。


1
你尝试过向请求中添加其他头部吗?例如:https://dev59.com/m2Yr5IYBdhLWcg3w6eI3 - Paul Rooney
3个回答

6

终于想明白了...

# grep python /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp

2
这真的帮了我很多,让我找到了正确的方向。谢谢!在CentOS 7上使用SELinux阻止了一个Python调用urllib/urllib2/requests从.py文件中进行,但是在Python命令行中却没有问题,而且错误信息也没有提供有用的提示。这让我疯狂了。 - John Marion

1

使用requests并提供User-Agent头对我有效:

from bs4 import BeautifulSoup
import requests

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36'}
response = requests.get("https://librivox.org/selections-from-battle-pieces-and-aspects-of-the-war-by-herman-melville/", headers=headers)

soup = BeautifulSoup(response.content)
print soup.title.text  # "prints LibriVox"

谢谢,但那只是给了我不同版本的错误 13。 - Red Cricket

0
我们的一台机器也遇到了同样的问题。与其创建一个SELinux模块(如上面的答案所列),我们对SELinux布尔值进行了以下更改,以防止类似的错误发生:
# setsebool httpd_can_network_connect on
正如CentOS Wiki所解释的那样:
httpd_can_network_connect(HTTPD服务):允许HTTPD脚本和模块连接到网络。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接