Как отправить еще один запрос и получить результат в функции scrapy parse? - PullRequest
0 голосов
/ 13 ноября 2018

Я анализирую HTML-страницу с двухуровневым меню. Когда меню верхнего уровня изменилось, был отправлен запрос AJAX для получения пункта меню второго уровня. Когда выбраны верхнее и второе меню, обновите содержимое.

Мне нужно отправить еще один запрос и получить ответ в подменю в функции scopy parse. Так что я могу перебрать подменю, построить scrapy.Request для каждого элемента подменю.

Псевдокод, подобный следующему:

def parse(self, response):
    top_level_menu = response.xpath('//TOP_LEVEL_MENU_XPATH')
    second_level_menu_items = ## HERE I NEED TO SEND A REQUEST AND GET RESULT, PARSED TO ITME VALUE LIST

    for second_menu_item in second_level_menu_items:
        yield scrapy.Request(response.urljoin(content_request_url + '?top_level=' + top_level_menu + '&second_level_menu=' + second_menu_item), callback=self.parse_content)

Как я могу это сделать?

Использование requests lib напрямую? Или какая-то другая функция, предоставляемая скрапом?

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

Просто используйте dont_filter = True для вашего запроса Пример:

def start_requests(self):
    return [Request(url=self.base_url, callback=self.parse_city)]

def parse_city(self, response):
    for next_page in response.css('a.category'):
        url = self.base_url + next_page.attrib['href']
        self.log(url)
        yield Request(url=url,  callback=self.parse_something_else, dont_filter=True)

def parse_something_else(self, response):
    for next_page in response.css('#contentwrapper > div > div > div.component > table > tbody > tr:nth-child(2) > td > form > table > tbody > tr'):
        url = self.base_url + next_page.attrib['href']
        self.log(url)
        yield Request(url=next_page, callback=self.parse, dont_filter=True)

def parse(self, response):
    pass
0 голосов
/ 13 ноября 2018

Рекомендованный подход здесь - создать еще один обратный вызов (parse_second_level_menus?) Для обработки ответа для пунктов меню второго уровня, а там создать запросы к страницам контента.

Кроме того, вы можете использовать атрибут request.meta для передачи данных между методами обратного вызова ( дополнительная информация здесь ).

Это может быть что-то вроде этого:

def parse(self, response):
    top_level_menu = response.xpath('//TOP_LEVEL_MENU_XPATH').get()
    yield scrapy.Request(
        some_url,
        callback=self.parse_second_level_menus,
        # pass the top_level_menu value to the other callback
        meta={'top_menu': top_level_menu},
    )

def parse_second_level_menus(self, response):
    # read the data passed in the meta by the first callback
    top_level_menu = response.meta.get('top_menu')
    second_level_menu_items = response.xpath('...').getall()

    for second_menu_item in second_level_menu_items:
        url = response.urljoin(content_request_url + '?top_level=' + top_level_menu + '&second_level_menu=' + second_menu_item)
        yield scrapy.Request(
            url,
            callback=self.parse_content
    )

def parse_content(self, response):
    ...

Еще один подход (менее рекомендуемый в этом случае) будет использовать эту библиотеку: https://github.com/rmax/scrapy-inline-requests

...