重定向请求的回调 Scrapy
Callback for redirected requests Scrapy
我正在尝试使用抓取框架进行抓取。一些请求被重定向,但在 start_requests 中设置的回调函数不会为这些重定向的 url 请求调用,但对于非重定向的请求可以正常工作。
我在 start_requests 函数中有以下代码:
for user in users:
yield scrapy.Request(url=userBaseUrl+str(user['userId']),cookies=cookies,headers=headers,dont_filter=True,callback=self.parse_p)
但此 self.parse_p 仅针对非 302 请求调用。
我猜你得到了最终页面的回调(重定向之后)。 RedirectMiddleware
负责重定向。您可以禁用它,然后您将不得不手动执行所有重定向。如果您想有选择地禁用某些类型的请求的重定向,您可以这样做:
request = scrapy.Request(url, meta={'dont_redirect': True} callback=self.manual_handle_of_redirects)
我不确定中间 Requests/Responses 是否很有趣。 RedirectMiddleware
也是这么认为的。因此,它会自动进行重定向并将中间 URL(唯一有趣的东西)保存在:
response.request.meta.get('redirect_urls')
你有几个选择!
示例蜘蛛:
import scrapy
class DimSpider(scrapy.Spider):
name = "dim"
start_urls = (
'http://example.com/',
)
def parse(self, response):
yield scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p)
def parse_p(self, response):
print response.request.meta.get('redirect_urls')
print "done!"
示例输出...
DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None)
DEBUG: Redirecting (302) to <GET http://myredirect.com> from <GET http://example.com/redirect302.php>
DEBUG: Crawled (200) <GET http://myredirect.com/> (referer: http://example.com/redirect302.com/)
['http://example.com/redirect302.php']
done!
如果你真的想抓取 302 页面,你必须明确地允许它。例如这里,我允许 302
并将 dont_redirect
设置为 True
:
handle_httpstatus_list = [302]
def parse(self, response):
r = scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p)
r.meta['dont_redirect'] = True
yield r
最后的结果是:
DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None)
DEBUG: Crawled (302) <GET http://example.com/redirect302.com/> (referer: http://www.example.com/)
None
done!
此蜘蛛程序应手动跟踪 302 网址:
import scrapy
class DimSpider(scrapy.Spider):
name = "dim"
handle_httpstatus_list = [302]
def start_requests(self):
yield scrapy.Request("http://page_with_or_without_redirect.html",
callback=self.parse200_or_302, meta={'dont_redirect':True})
def parse200_or_302(self, response):
print "I'm on: %s with status %d" % (response.url, response.status)
if 'location' in response.headers:
print "redirecting"
return [scrapy.Request(response.headers['Location'],
callback=self.parse200_or_302, meta={'dont_redirect':True})]
小心。不要省略设置 handle_httpstatus_list = [302]
否则你会得到 "HTTP status code is not handled or not allowed".
默认情况下,scrapy 不遵循 302 重定向。
在您的蜘蛛中,您可以使用 custom_settings 属性:
custom_settings
A dictionary of settings that will be overridden from the project wide configuration when running this spider. It must be defined as a class attribute since the settings are updated before instantiation.
设置 url 请求可以重定向的重定向次数,如下所示:
class MySpider(scrapy.Spider):
name = "myspider"
allowed_domains = ["example.com"]
start_urls = [ "http://www.example.com" ]
custom_settings = { 'REDIRECT_MAX_TIMES': 333 }
def start_requests(self):
# Your code here
我以333为例。
希望对您有所帮助。
我正在尝试使用抓取框架进行抓取。一些请求被重定向,但在 start_requests 中设置的回调函数不会为这些重定向的 url 请求调用,但对于非重定向的请求可以正常工作。
我在 start_requests 函数中有以下代码:
for user in users:
yield scrapy.Request(url=userBaseUrl+str(user['userId']),cookies=cookies,headers=headers,dont_filter=True,callback=self.parse_p)
但此 self.parse_p 仅针对非 302 请求调用。
我猜你得到了最终页面的回调(重定向之后)。 RedirectMiddleware
负责重定向。您可以禁用它,然后您将不得不手动执行所有重定向。如果您想有选择地禁用某些类型的请求的重定向,您可以这样做:
request = scrapy.Request(url, meta={'dont_redirect': True} callback=self.manual_handle_of_redirects)
我不确定中间 Requests/Responses 是否很有趣。 RedirectMiddleware
也是这么认为的。因此,它会自动进行重定向并将中间 URL(唯一有趣的东西)保存在:
response.request.meta.get('redirect_urls')
你有几个选择!
示例蜘蛛:
import scrapy
class DimSpider(scrapy.Spider):
name = "dim"
start_urls = (
'http://example.com/',
)
def parse(self, response):
yield scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p)
def parse_p(self, response):
print response.request.meta.get('redirect_urls')
print "done!"
示例输出...
DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None)
DEBUG: Redirecting (302) to <GET http://myredirect.com> from <GET http://example.com/redirect302.php>
DEBUG: Crawled (200) <GET http://myredirect.com/> (referer: http://example.com/redirect302.com/)
['http://example.com/redirect302.php']
done!
如果你真的想抓取 302 页面,你必须明确地允许它。例如这里,我允许 302
并将 dont_redirect
设置为 True
:
handle_httpstatus_list = [302]
def parse(self, response):
r = scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p)
r.meta['dont_redirect'] = True
yield r
最后的结果是:
DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None)
DEBUG: Crawled (302) <GET http://example.com/redirect302.com/> (referer: http://www.example.com/)
None
done!
此蜘蛛程序应手动跟踪 302 网址:
import scrapy
class DimSpider(scrapy.Spider):
name = "dim"
handle_httpstatus_list = [302]
def start_requests(self):
yield scrapy.Request("http://page_with_or_without_redirect.html",
callback=self.parse200_or_302, meta={'dont_redirect':True})
def parse200_or_302(self, response):
print "I'm on: %s with status %d" % (response.url, response.status)
if 'location' in response.headers:
print "redirecting"
return [scrapy.Request(response.headers['Location'],
callback=self.parse200_or_302, meta={'dont_redirect':True})]
小心。不要省略设置 handle_httpstatus_list = [302]
否则你会得到 "HTTP status code is not handled or not allowed".
默认情况下,scrapy 不遵循 302 重定向。
在您的蜘蛛中,您可以使用 custom_settings 属性:
custom_settings A dictionary of settings that will be overridden from the project wide configuration when running this spider. It must be defined as a class attribute since the settings are updated before instantiation.
设置 url 请求可以重定向的重定向次数,如下所示:
class MySpider(scrapy.Spider):
name = "myspider"
allowed_domains = ["example.com"]
start_urls = [ "http://www.example.com" ]
custom_settings = { 'REDIRECT_MAX_TIMES': 333 }
def start_requests(self):
# Your code here
我以333为例。
希望对您有所帮助。