我有一个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
答案 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
标头,但Referrer
和Accept
等其他标头也经常涉及。这不是requests
中的错误。
这取决于每个特定的站点配置它们的行为方式。您可以尝试设置其他标头,例如User-Agent
,以尝试欺骗桌面浏览器,但请注意并非所有网站都欢迎此类行为。如果您要抓取某个网站,请尝试遵守他们的/robots.txt
政策,并且不要请求您没有的蜘蛛网站。如果您想自动执行此过程,可以使用Python附带的robotparser
module。
您可以使用headers
参数设置其他标头requests.get()
:
headers = {'User-Agent': 'FooBar-Spider 1.0'}
response = requests.get(site, headers=headers)
但是,如果某个网站明确要求您不要使用它们,请不要欺骗浏览器用户代理字符串。