adds ROBOTSTXT_USER_AGENT setting

This commit is contained in:
Anubhav Patel 2019-08-19 09:19:06 +05:30
parent a95de71d8e
commit 00fe05e536
5 changed files with 45 additions and 2 deletions

View File

@ -1074,6 +1074,21 @@ implementing the methods described below.
.. autoclass:: RobotParser
:members:
RobotsTxtMiddleware Settings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. setting:: ROBOTSTXT_USER_AGENT
ROBOTSTXT_USER_AGENT
^^^^^^^^^^^^^^^^^^^^
Default: ``None``
The user agent string to use for matching in the robots.txt_ file. If ``None``,
the User-Agent header you are sending with the request or the
:setting:`USER_AGENT` setting (in that order) will be used for determining
the user agent to use in the robots.txt_ file.
.. _robots.txt: http://www.robotstxt.org/
DownloaderStats

View File

@ -1151,6 +1151,18 @@ Default: ``'scrapy.robotstxt.PythonRobotParser'``
The parser backend to use for parsing ``robots.txt`` files. For more information see
:ref:`topics-dlmw-robots`.
.. setting:: ROBOTSTXT_USER_AGENT
ROBOTSTXT_USER_AGENT
^^^^^^^^^^^^^^^^^^^^
Default: ``None``
The user agent string to use for matching in the robots.txt file. If ``None``,
the User-Agent header you are sending with the request or the
:setting:`USER_AGENT` setting (in that order) will be used for determining
the user agent to use in the robots.txt file.
.. setting:: SCHEDULER
SCHEDULER
@ -1409,7 +1421,9 @@ USER_AGENT
Default: ``"Scrapy/VERSION (+https://scrapy.org)"``
The default User-Agent to use when crawling, unless overridden.
The default User-Agent to use when crawling, unless overridden. This user agent is
also used in robots.txt if :setting:`ROBOTSTXT_USER_AGENT` setting is ``None`` and
there is no overridding User-Agent header specified for the request.
Settings documented elsewhere:

View File

@ -26,6 +26,7 @@ class RobotsTxtMiddleware(object):
if not crawler.settings.getbool('ROBOTSTXT_OBEY'):
raise NotConfigured
self._default_useragent = crawler.settings.get('USER_AGENT', 'Scrapy')
self._robotstxt_useragent = crawler.settings.get('ROBOTSTXT_USER_AGENT', None)
self.crawler = crawler
self._parsers = {}
self._parserimpl = load_object(crawler.settings.get('ROBOTSTXT_PARSER'))
@ -47,7 +48,10 @@ class RobotsTxtMiddleware(object):
def process_request_2(self, rp, request, spider):
if rp is None:
return
useragent = request.headers.get(b'User-Agent', self._default_useragent)
useragent = self._robotstxt_useragent
if not useragent:
useragent = request.headers.get(b'User-Agent', self._default_useragent)
if not rp.allowed(request.url, useragent):
logger.debug("Forbidden by robots.txt: %(request)s",
{'request': request}, extra={'spider': spider})

View File

@ -246,6 +246,7 @@ RETRY_PRIORITY_ADJUST = -1
ROBOTSTXT_OBEY = False
ROBOTSTXT_PARSER = 'scrapy.robotstxt.PythonRobotParser'
ROBOTSTXT_USER_AGENT = None
SCHEDULER = 'scrapy.core.scheduler.Scheduler'
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleLifoDiskQueue'

View File

@ -164,6 +164,15 @@ Disallow: /some/randome/page.html
d.addCallback(lambda _: self.assertFalse(mw_module_logger.error.called))
return d
def test_robotstxt_user_agent_setting(self):
crawler = self._get_successful_crawler()
crawler.settings.set('ROBOTSTXT_USER_AGENT', 'Examplebot')
crawler.settings.set('USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64)')
middleware = RobotsTxtMiddleware(crawler)
rp = mock.MagicMock(return_value=True)
middleware.process_request_2(rp, Request('http://site.local/allowed'), None)
rp.allowed.assert_called_once_with('http://site.local/allowed', 'Examplebot')
def assertNotIgnored(self, request, middleware):
spider = None # not actually used
dfd = maybeDeferred(middleware.process_request, request, spider)