Выглядит хорошо для новичка в разработке!Я изменил только селектор в вас parse
функция:
for quote in response.css('div.block-list div.item'):
yield {
'text': quote.css('h3.headline::text').get(),
}
UPD: хм, похоже, ваш сайт делает дополнительный запрос данных.
Откройте инструменты разработчика и проверьте запрос на https://www.mckinsey.com/services/ContentAPI/SearchAPI.svc/search
с параметрами {"q":"Agile","page":1,"app":"","sort":"default","ignoreSpellSuggestion":false}
.Вы можете сделать scrapy.Request
с этими параметрами и соответствующими заголовками и получить JSON с данными.Он будет легко проанализирован с помощью json
lib.
UPD2: как я вижу из этого скручивания curl 'https://www.mckinsey.com/services/ContentAPI/SearchAPI.svc/search' -H 'content-type: application/json' --data-binary '{"q":"Agile","page”:1,”app":"","sort":"default","ignoreSpellSuggestion":false}' --compressed
, нам нужно сделать запрос следующим образом:
from scrapy import Request
import json
data = {"q": "Agile", "page": 1, "app": "", "sort": "default", "ignoreSpellSuggestion": False}
headers = {"content-type": "application/json"}
url = "https://www.mckinsey.com/services/ContentAPI/SearchAPI.svc/search"
yield Request(url, headers=headers, body=json.dumps(data), callback=self.parse_api)
, а затемв parse_api
функция просто разобрать ответ:
def parse_api(self, response):
data = json.loads(response.body)
# and then extract what you need
Таким образом, вы можете перебрать параметр page
в запросе и получить все страницы.
UPD3: Рабочее решение:
from scrapy import Spider, Request
import json
class BrickSetSpider(Spider):
name = "brickset_spider"
data = {"q": "Agile", "page": 1, "app": "", "sort": "default", "ignoreSpellSuggestion": False}
headers = {"content-type": "application/json"}
url = "https://www.mckinsey.com/services/ContentAPI/SearchAPI.svc/search"
def start_requests(self):
yield Request(self.url, headers=self.headers, method='POST',
body=json.dumps(self.data), meta={'page': 1})
def parse(self, response):
data = json.loads(response.body)
results = data.get('data', {}).get('results')
if not results:
return
for row in results:
yield {'title': row.get('title')}
page = response.meta['page'] + 1
self.data['page'] = page
yield Request(self.url, headers=self.headers, method='POST', body=json.dumps(self.data), meta={'page': page})