如何使用Scrapy进行多页面报废?

时间:2017-03-06 17:23:10

标签: python python-2.7 web-scraping scrapy

#----\
#-----*-----\
#----/       \ 
              \
#----\         \
#-----*-------- *  <-- START
#----/         /
              / 
#----\       /
#-----*-----/     
#----/

这是我想用scrapy废弃的网站的结构,其中*是页面,---表示链接。我想刮掉#page的数据。 我已经完成了一个可以从单个#页面抓取数据的刮刀。

import scrapy


class MyItem(scrapy.Item):
    topic = scrapy.Field()
    symptoms = scrapy.Field()


class QuotesSpider(scrapy.Spider):
    name = "medical"

    allowed_domains = ['medlineplus.gov']
    start_urls = ['https://medlineplus.gov/ency/article/000178.htm']

    def parse(self, response):
        item = MyItem()

        item["topic"] = response.css('h1.with-also::text').extract_first()
        item["symptoms"] = response.css("article div#section-2 li::text").extract()

        yield item

起始网页为https://medlineplus.gov/encyclopedia.html 我想在百科全书中搜集有关所有疾病的信息。

1 个答案:

答案 0 :(得分:2)

您需要从“encyclopedia.html”页面开始,按照“alpha”链接(A-Z文章链接),然后,对于每个后续页面,请点击文章链接。

您可以使用CrawlSpiderLink Extractors执行此操作,但由于抓取深度很小,我们可以使用常规Spider执行此操作:

from urlparse import urljoin  # Python 2 only

import scrapy
from scrapy.http import Request


class MyItem(scrapy.Item):
    topic = scrapy.Field()
    symptoms = scrapy.Field()


class MedicalSpider(scrapy.Spider):
    name = "medical"

    allowed_domains = ['medlineplus.gov']
    start_urls = ['https://medlineplus.gov/encyclopedia.html']

    def parse(self, response):
        for link in response.css("ul.alpha-links li a::attr(href)").extract():
            yield Request(urljoin(response.url, link), callback=self.parse_alpha_page)

    def parse_alpha_page(self, response):
        for link in response.css("ul#index li a::attr(href)").extract():
            yield Request(urljoin(response.url, link), callback=self.parse_page)

    def parse_page(self, response):
        item = MyItem()

        item["topic"] = response.css('h1.with-also::text').extract_first()
        item["symptoms"] = response.css("article div#section-2 li::text").extract()

        yield item

请注意,似乎有更好的方法从MedlinePlus获取所需数据(请查看"For Developers" page)。