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

StackOverflow https://stackoverflow.com/questions/5825880

  •  26-10-2019
  •  | 
  •  

Вопрос

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

Но каждый элемент имеет среди других данных, URL, с более подробной информацией об этом элементе. Я хочу следовать этому URL и сохранить в другом поле предметов (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()
Это было полезно?

Решение

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

А в 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 дней, я считаю, что единственное решение-следовать этому URL-адресу вручную, из вашего parse_item функция

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top