使用基本身份验证抓取端点
Scrape endpoint with Basic authentication
我正在尝试抓取 this web. When you select an option in the first selector, the web sends a GET request to this 后端端点,然后使用 Javascript 动态填充下一个选择器选项。我想用 Scrapy 执行相同的 GET 请求,问题是你需要一个基本身份验证密钥才能访问该端点。
身份验证凭据会在您第一次访问该页面时保存,因此如果您尝试通过浏览器访问该端点,则可以毫无问题地进行。但是,如果您转到私人 window 并直接转到端点而不先访问网络,您会注意到出现浮动 window 要求您进行身份验证。
我正在尝试使用 Scrapy 复制此行为,但是当我将请求发送到端点时,我收到了 401 响应。
from scrapy import Spider
from scrapy.http import Request
class MIRSpider(Spider):
name = 'MIRScrapper'
allowed_domains = ['infoelectoral.interior.gob.es']
custom_settings = {
'SPIDER_MIDDLEWARES': {
'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': None,
CustomHttpErrorMiddleware: 50
}
}
start_urls = ['https://infoelectoral.interior.gob.es/opencms/es/elecciones-celebradas/area-de-descargas/']
types_url = 'https://infoelectoral.interior.gob.es/min/convocatorias/tipos/'
def parse(self, response):
yield Request(
url=self.types_url,
method='GET',
callback=self.parse_types,
)
def parse_types(self, response):
print(response)
我不知道如何让 Scrapy 在第一次访问起始 url 时获取授权凭据,并使用它们来设置第二个请求中的 headers。我检查了我的浏览器网络选项卡,得到了我的浏览器发送的 header 中的 Authorization
字段,并像这样使用它:
def parse(self, response):
required_header = {
'Authorization': 'Basic YXBpSW5mb2VsZWN0b3JhbDphcGlJbmZvZWxlY3RvcmFsUHJv'
}
yield Request(
url=self.types_url,
method='GET',
headers=required_header,
callback=self.parse_types,
)
我能够从端点获取信息,但我认为这不是一个有效的解决方案,因为密钥将来可能会更改,每次发生时我都必须更改代码。
没有任何中间件或类似的东西可以处理基本授权凭据吗?我必须以某种方式设置它吗?
您的 required_header
解决方案几乎是您可以直接从此端点获取信息的唯一方法。另一种方法是使用真正的浏览器(Selenium、Splash 等)来迭代这个站点(但它会慢得多)。
在这种情况下没有处理 Authorization
header 的中间件,因为此 header 是使用 Javascript 动态发送的(检查 https://infoelectoral.interior.gob.es/opencms/export/system/modules/com.infoelectoral.mapaleaflet/resources/js/index.js示例)使用如下命令:
request.setRequestHeader("Authorization", "Basic "+btoa("apiInfoelectoral:apiInfoelectoralPro"));
当然,您可以创建一个脚本来解析上述 Javascript 文件中的登录名/密码,但不能保证网站所有者会更改上述代码段...
我正在尝试抓取 this web. When you select an option in the first selector, the web sends a GET request to this 后端端点,然后使用 Javascript 动态填充下一个选择器选项。我想用 Scrapy 执行相同的 GET 请求,问题是你需要一个基本身份验证密钥才能访问该端点。
身份验证凭据会在您第一次访问该页面时保存,因此如果您尝试通过浏览器访问该端点,则可以毫无问题地进行。但是,如果您转到私人 window 并直接转到端点而不先访问网络,您会注意到出现浮动 window 要求您进行身份验证。
我正在尝试使用 Scrapy 复制此行为,但是当我将请求发送到端点时,我收到了 401 响应。
from scrapy import Spider
from scrapy.http import Request
class MIRSpider(Spider):
name = 'MIRScrapper'
allowed_domains = ['infoelectoral.interior.gob.es']
custom_settings = {
'SPIDER_MIDDLEWARES': {
'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': None,
CustomHttpErrorMiddleware: 50
}
}
start_urls = ['https://infoelectoral.interior.gob.es/opencms/es/elecciones-celebradas/area-de-descargas/']
types_url = 'https://infoelectoral.interior.gob.es/min/convocatorias/tipos/'
def parse(self, response):
yield Request(
url=self.types_url,
method='GET',
callback=self.parse_types,
)
def parse_types(self, response):
print(response)
我不知道如何让 Scrapy 在第一次访问起始 url 时获取授权凭据,并使用它们来设置第二个请求中的 headers。我检查了我的浏览器网络选项卡,得到了我的浏览器发送的 header 中的 Authorization
字段,并像这样使用它:
def parse(self, response):
required_header = {
'Authorization': 'Basic YXBpSW5mb2VsZWN0b3JhbDphcGlJbmZvZWxlY3RvcmFsUHJv'
}
yield Request(
url=self.types_url,
method='GET',
headers=required_header,
callback=self.parse_types,
)
我能够从端点获取信息,但我认为这不是一个有效的解决方案,因为密钥将来可能会更改,每次发生时我都必须更改代码。
没有任何中间件或类似的东西可以处理基本授权凭据吗?我必须以某种方式设置它吗?
您的 required_header
解决方案几乎是您可以直接从此端点获取信息的唯一方法。另一种方法是使用真正的浏览器(Selenium、Splash 等)来迭代这个站点(但它会慢得多)。
在这种情况下没有处理 Authorization
header 的中间件,因为此 header 是使用 Javascript 动态发送的(检查 https://infoelectoral.interior.gob.es/opencms/export/system/modules/com.infoelectoral.mapaleaflet/resources/js/index.js示例)使用如下命令:
request.setRequestHeader("Authorization", "Basic "+btoa("apiInfoelectoral:apiInfoelectoralPro"));
当然,您可以创建一个脚本来解析上述 Javascript 文件中的登录名/密码,但不能保证网站所有者会更改上述代码段...