Подтвердить что ты не робот

Scrapy - анализировать страницу для извлечения элементов - затем следовать и хранить содержимое URL-адреса элемента

У меня вопрос о том, как это сделать в процессе лечения. У меня есть паук, который сканирует список страниц. Каждый раз, когда отображается страница листинга с элементами, существует обратный вызов parse_item(), который вызывается для извлечения данных элементов и получения элементов. Пока все хорошо, все отлично работает.

Но каждый элемент имеет среди других данных URL-адрес, с более подробной информацией об этом элементе. Я хочу следовать этому url и хранить в другом поле item (url_contents) выбранное содержимое этого URL-адреса элемента.

И я не уверен, как организовать код для достижения этого, поскольку две ссылки (ссылки ссылок и одна ссылка на конкретный элемент) выполняются по-разному, с обратными вызовами, вызываемыми в разное время, но я должен их сопоставить в та же обработка элементов.

Мой код выглядит так:

class MySpider(CrawlSpider):
    name = "example.com"
    allowed_domains = ["example.com"]
    start_urls = [
        "http://www.example.com/?q=example",
    ]

    rules = (
        Rule(SgmlLinkExtractor(allow=('example\.com', 'start='), deny=('sort='), restrict_xpaths = '//div[@class="pagination"]'), callback='parse_item'),
        Rule(SgmlLinkExtractor(allow=('item\/detail', )), follow = False),
    )


    def parse_item(self, response):
        main_selector = HtmlXPathSelector(response)
        xpath = '//h2[@class="title"]'

        sub_selectors = main_selector.select(xpath)

        for sel in sub_selectors:
            item = ExampleItem()
            l = ExampleLoader(item = item, selector = sel)
            l.add_xpath('title', 'a[@title]/@title')
            ......
            yield l.load_item()
4b9b3361

Ответ 1

После некоторого тестирования и мышления я нашел это решение, которое работает для меня. Идея состоит в том, чтобы использовать только первое правило, которое дает вам списки предметов, а также очень важно добавить follow = True в это правило.

И в parse_item() вы должны предоставить запрос вместо элемента, но после загрузки элемента. Запрос на URL-адрес деталя. И вы должны отправить загруженный элемент в обратный вызов этого запроса. Вы выполняете свою работу с ответом, и там вы получаете элемент.

Итак, финиш parse_item() будет выглядеть так:

itemloaded = l.load_item()

# fill url contents
url = sel.select(item_url_xpath).extract()[0]
request = Request(url, callback = lambda r: self.parse_url_contents(r))
request.meta['item'] = itemloaded

yield request

И тогда parse_url_contents() будет выглядеть так:

def parse_url_contents(self, response):
    item = response.request.meta['item']
    item['url_contents'] = response.body
    yield item

Если у кого-то есть другой (лучший) подход, сообщите нам.

Стефан

Ответ 2

Я сижу с точно такой же проблемой, и из-за того, что никто не ответил на ваш вопрос в течение 2 дней, я полагаю, что единственным решением является следовать этому URL-адресу вручную из функции parse_item.

Я новичок в Scrapy, поэтому я бы не попытался с этим (хотя я уверен, что это возможно), но мое решение будет заключаться в использовании urllib и BeatifulSoup для загрузки второй страницы вручную, информацию и сохранить ее как часть предмета. Да, гораздо больше проблем, чем Scrapy, делает обычный синтаксический анализ, но он должен выполнять работу с наименьшими проблемами.