admin 管理员组

文章数量: 887017

我有一个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

[...]

Progress: [=========-] 87.8% Failed to load site : http://www.hotchalk

Progress: [=========-] 93.2% Failed to load site : http://Hollywire

Progress: [=========-] 93.8% Failed to load site : http://www.Allplaybook

但是,如果我在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", allow_redirects=True)

>>> content

>>> content.text

u'<?xml version="1.0" encoding="utf-8"?>\r\n...]

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

>>> content = requests.get("http://www.hotchalk", allow_redirects=True)

>>> content

>>> content.text

u'\r\n

403 Forbidden\r\n\r\n

403 Forbidden

\r\n
nginx
\r\n\r\n\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,我会寻找涉及指针和未定义行为的东西,但是我似乎找不到任何可能引起类似结果的东西。

编辑:

使用robotparserser模块,我尝试检查上述站点的 robots.txt文件之一,并注意到该文件User-agent: *位于最顶部。我看不到任何条目,这些条目否则会禁止我访问其索引页,因此这可能是由其他原因引起的吗?

在Python Shell中:

>>> import robotparser

>>> rp = robotparser.RobotFileParser()

>>> rp = robotparser.RobotFileParser()

>>> rp.set_url("http://www.mocospace/robots.txt")

>>> rp.read()

>>> rp.can_fetch("*", "http://www.mocospace")

True

解决方案

默认情况下,requests服务器发送响应时不引发异常。如果要requests引发4xx或5xx响应代码的异常,则需要明确告知它这样做:

response = requests.get(site, allow_redirects = True)

response.raise_for_status()

content = response.text

或检查response.status_code属性,并根据其值更改您的行为。另请参阅快速入门中的响应状态代码。

至于用调用时表现不同的网站requests;请记住,HTTP服务器本质上是黑匣子。在HTTP RFC中,他们可以根据需要自由响应。这包括对标头进行过滤,并根据请求中的所有内容更改行为,直至并包括完全随机响应。

您的浏览器发送的标头集与发送的标头集不同requests;通常的罪魁祸首是User-Agent标头,但也经常涉及其他标头,例如Referrer和Accept。这不是中的错误requests。

取决于每个特定的站点配置,它们的表现如何。您可以尝试设置其他标题,例如User-Agent尝试和欺骗桌面浏览器,但要考虑到并非所有站点都欢迎这种行为。如果您要搜寻某个网站,请尝试遵守其/robots.txt政策,不要搜寻要求您不这样做的网站。如果要自动化此过程,可以使用Python随附的robotparser模块。

您可以将其他标头设置为headers参数requests.get():

headers = {'User-Agent': 'FooBar-Spider 1.0'}

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

but again, don't spoof browser user agent strings if a site is clearly asking you not to spider them.

本文标签: 打不开 无法打开 浏览器 网页 网站