Соскрести несколько статей с одной страницы с каждой статьей с отдельной ссылкой - PullRequest
0 голосов
/ 09 июля 2019

Я новичок в области scrapy и пишу свой первый паук, чтобы сделать scrapy spider для сайта, похожего на https://blogs.webmd.com/diabetes/default.htm

Я хочу почистить заголовки, а затем перейти к каждой статье и прочистить текст для каждой статьи.

Я пытался с помощью правил и linkextractor, но он не может перейти на следующую страницу и извлечь. я получаю ОШИБКУ: обработка ошибки Spider https://blogs.webmd.com/diabetes/default.htm> (реферер: нет)

Ниже мой код

import scrapy
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor


class MedicalSpider(scrapy.Spider):
    name = 'medical'
    allowed_domains = ['https://blogs.webmd.com/diabetes/default.htm']
    start_urls = ['https://blogs.webmd.com/diabetes/default.htm']

    Rules = (Rule(LinkExtractor(allow=(), restrict_css=('.posts-list-post-content a ::attr(href)')), callback="parse", follow=True),)
    def parse(self, response):
        headline = response.css('.posts-list-post-content::text').extract()
        body = response.css('.posts-list-post-desc::text').extract()
        print("%s : %s" % (headline, body))

        next_page = response.css('.posts-list-post-content a ::attr(href)').extract()
        if next_page:
            next_href = next_page[0]
            next_page_url = next_href
            request = scrapy.Request(url=next_page_url)
            yield request

Пожалуйста, ведите новичка в области скрапа, чтобы этот паук подходил для нескольких статей на каждой странице.

1 Ответ

1 голос
/ 09 июля 2019

Обычно при использовании scrapy каждый ответ анализируется с помощью parse callback . Основной метод parse является обратным вызовом для начального ответа, полученного для каждого из start_urls.

Цель этой функции разбора должна заключаться в том, чтобы «определить ссылки на статьи» и выдавать запросы для каждой из них. Эти ответы затем будут проанализированы другим обратным вызовом, скажем, parse_article, который затем извлечет все содержимое этой конкретной статьи.

Тебе даже не нужно это LinkExtractor. Рассмотрим:

import scrapy

class MedicalSpider(scrapy.Spider):
    name = 'medical'
    allowed_domains = ['blogs.webmd.com'] # Only the domain, not the URL
    start_urls = ['https://blogs.webmd.com/diabetes/default.htm']

    def parse(self, response):
        article_links = response.css('.posts-list-post-content a ::attr(href)')
        for link in article_links:
            url = link.get()
            if url:
                yield response.follow(url=url, callback=self.parse_article)

    def parse_article(self, response):
        headline = 'some-css-selector-to-get-the-headline-from-the-aticle-page'

        # The body is trickier, since it's spread through several tags on this particular site
        body = 'loop-over-some-selector-to-get-the-article-text'

        yield {
            'headline': headline,
            'body': body
        }

Я не вставил полный код, потому что я думаю, что вы все еще хотите узнать, как это сделать, но вы можете найти то, что я придумал в этом gist

Обратите внимание, что метод parse_article возвращает словари. Они используют конвейеры предметов Scrapy. Вы можете получить аккуратный вывод json, запустив код с помощью: scrapy runspider headlines/spiders/medical.py -o out.json

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