Scrapy - анализ страницы для извлечения элементов, затем отслеживание и сохранение содержимого URL-адресов - PullRequest
23 голосов
/ 29 апреля 2011

У меня вопрос о том, как сделать это в скрапе. У меня есть паук, который ползет по списку страниц предметов. Каждый раз, когда найдена страница листинга с элементами, существует обратный вызов 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()

Ответы [ 2 ]

20 голосов
/ 02 мая 2011

После некоторого тестирования и размышлений я нашел это решение, которое работает для меня.Идея состоит в том, чтобы использовать только первое правило, которое дает вам списки элементов, а также, что очень важно, добавить 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

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

Стефан

1 голос
/ 01 мая 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...