使用mechanize检索robots.txt时出现HTTP 403错误。
使用mechanize检索robots.txt时出现HTTP 403错误。
这个shell命令成功地打印出了robots.txt文件:
$ curl -A "Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0 (compatible;)" http://fifa-infinity.com/robots.txt
忽略了user-agent选项会导致服务器返回403错误。检查robots.txt文件发现允许爬取http://www.fifa-infinity.com/board下的内容。然而,以下Python代码失败了:
import logging import mechanize from mechanize import Browser ua = 'Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0 (compatible;)' br = Browser() br.addheaders = [('User-Agent', ua)] br.set_debug_http(True) br.set_debug_responses(True) logging.getLogger('mechanize').setLevel(logging.DEBUG) br.open('http://www.fifa-infinity.com/robots.txt')
在我的控制台上输出如下:
No handlers could be found for logger "mechanize.cookies" send: 'GET /robots.txt HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: www.fifa-infinity.com\r\nConnection: close\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0 (compatible;)\r\n\r\n' reply: 'HTTP/1.1 403 Bad Behavior\r\n' header: Date: Wed, 13 Feb 2013 15:37:16 GMT header: Server: Apache header: X-Powered-By: PHP/5.2.17 header: Vary: User-Agent,Accept-Encoding header: Connection: close header: Transfer-Encoding: chunked header: Content-Type: text/html Traceback (most recent call last): File "", line 1, in File "/home/moshev/Projects/forumscrawler/lib/python2.7/site-packages/mechanize/_mechanize.py", line 203, in open return self._mech_open(url, data, timeout=timeout) File "/home/moshev/Projects/forumscrawler/lib/python2.7/site-packages/mechanize/_mechanize.py", line 255, in _mech_open raise response mechanize._response.httperror_seek_wrapper: HTTP Error 403: Bad Behavior
奇怪的是,使用curl而不设置user-agent会导致返回"403: Forbidden"而不是"403: Bad Behavior"。
我是否做错了什么,还是mechanize/urllib2中存在bug?我不明白为什么仅仅获取robots.txt会被视为"bad behaviour"。
问题:HTTP 403错误在使用机械化工具检索机器人.txt时出现
原因:实验证明,需要添加一个“接受”头来指定可接受的内容类型(任何类型都可以,只要存在“接受”头)。例如,将代码中的'br.addheaders = [('User-Agent', ua)]'更改为'br.addheaders = [('User-Agent', ua), ('Accept', '*/*')]'后,问题将得到解决。
解决方法:将代码中的'br.addheaders = [('User-Agent', ua)]'更改为'br.addheaders = [('User-Agent', ua), ('Accept', '*/*')]'。这样做可以为请求添加一个“接受”头,指定可接受的内容类型。