Python Requests库有时无法打开浏览器可以打开的站点

时间:2014-12-11 12:30:50

标签: python python-requests

我有一个Python项目,我需要遍历众多网站并解析它们。

我注意到,在多个实例中,requests无法正确获取网站内容,即使该网站在Chrome和FF中打开也不错。例如,在我的代码中:

def get_site_content(site):
    try :
        content = requests.get(site, allow_redirects = True)
        content = content.text
    except Exception as e:
        if DEBUG :
            print type(e)
            print e.args
            print e
        global errors
        errors += 1
        return ''

    soup = BeautifulSoup(content)
    # parse, tokenize and filter the content of the site
    [...]
    return tokenized_content  

之后,我会检查网站内容是否为''。如果是这样,我知道发生了错误,并打印出该网站加载失败的情况。

在我的日志中:

Progress: [=========-] 1.8% Failed to load site : http://www.mocospace.com
[...]
Progress: [=========-] 87.8% Failed to load site : http://www.hotchalk.com
Progress: [=========-] 93.2% Failed to load site : http://Hollywire.com
Progress: [=========-] 93.8% Failed to load site : http://www.Allplaybook.com

但是,如果我在Python shell中运行完全相同的代码:

$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> content = requests.get("http://www.mocospace.com", allow_redirects=True)
>>> content
<Response [200]>
>>> content.text
u'<?xml version="1.0" encoding="utf-8"?>\r\n<!DOCTYPE html PUBLIC [...]

在我得到403的情况下,它仍然不是例外 - 应该如此。

>>> content = requests.get("http://www.hotchalk.com", allow_redirects=True)
>>> content
<Response [403]>
>>> content.text
u'<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body bgcolor="white">\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n'

日志表示加载失败的方式是,如果引发了get_site_content()返回''的错误:

# data is a list of all urls together with their category
for row in data:
    content = get_site_content(row['URL'])

    if content :
        classifier_data.append((content, row['Category']))
    else :
        print "Failed to load site : %s" % row['URL']

这种行为可能是由什么造成的?如果这是C,我会寻找涉及指针和未定义行为的东西,但我似乎无法找到任何可能导致类似内容的东西。


修改

使用robotparser模块,我尝试检查one of the above sites' robots.txt个文件,并注意到User-agent: *设置在最顶层。我没有看到任何不允许我访问其索引页面的条目,所以这可能是由其他原因造成的吗?

在Python shell中:

>>> import robotparser
>>> rp = robotparser.RobotFileParser()
>>> rp = robotparser.RobotFileParser()
>>> rp.set_url("http://www.mocospace.com/robots.txt")
>>> rp.read()
>>> rp.can_fetch("*", "http://www.mocospace.com")
True

1 个答案:

答案 0 :(得分:1)

默认情况下,requests在服务器发送响应时不会引发异常。如果您希望requests引发4xx或5xx响应代码的异常,那么您需要明确告诉它这样做:

response = requests.get(site, allow_redirects = True)
response.raise_for_status()
content = response.text

或检查response.status_code属性并根据其值更改您的行为。另请参阅快速入门中的Response Status Codes

对于使用requests调用时网站的行为不同;请记住,HTTP服务器基本上是黑盒子。在HTTP RFC中,他们可以随意响应。这包括过滤标题并根据请求中的所有更改行为,包括完全随机的响应。

您的浏览器会发送一组不同于requests的标头;通常的罪魁祸首是User-Agent标头,但ReferrerAccept等其他标头也经常涉及。这不是requests 中的错误。

这取决于每个特定的站点配置它们的行为方式。您可以尝试设置其他标头,例如User-Agent,以尝试欺骗桌面浏览器,但请注意并非所有网站都欢迎此类行为。如果您要抓取某个网站,请尝试遵守他们的/robots.txt政策,并且不要请求您没有的蜘蛛网站。如果您想自动执行此过程,可以使用Python附带的robotparser module

您可以使用headers参数设置其他标头requests.get()

headers = {'User-Agent': 'FooBar-Spider 1.0'}
response = requests.get(site, headers=headers)

但是,如果某个网站明确要求您不要使用它们,请不要欺骗浏览器用户代理字符串。