【问题标题】:Scrape Multiple articles from one page with each article with separate href从一页中抓取多篇文章,每篇文章都有单独的href
【发布时间】:2019-07-10 01:00:26
【问题描述】:

我是 scrapy 的新手,正在编写我的第一个蜘蛛,为类似于 https://blogs.webmd.com/diabetes/default.htm 的网站制作了一个 scrapy 蜘蛛

我想抓取标题,然后导航到每篇文章,抓取每篇文章的文本内容。

我尝试过使用规则和链接提取器,但它无法导航到下一页并提取。我得到错误:蜘蛛错误处理 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

请指导一个scrapy的新手,让这个蜘蛛正确地处理每个页面上的多篇文章。

【问题讨论】:

    标签: python-3.x scrapy


    【解决方案1】:

    通常在使用 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

    【讨论】:

    • 对于下一页,我正在使用以下代码导航,但下一页的响应为空? url_apnd = "blogs.webmd.com/diabetes" next_page = response.css('.next a ::attr(href)').extract_first() print("下一页 %s :",next_page) print("URL" + response.urljoin (next_page)) if next_page: yield scrapy.Request(response.urljoin(url_apnd,next_page),callback=self.parse)
    • 嗨。我真的无法理解该代码。请为此使用代码格式。基本上,您需要为 Crawling other pages 执行的操作是在 parse 方法上的 for 循环之后向 yield 另一个请求到下一页。
    • 我已经更新了要点,虽然我并没有真正运行它。
    • 我在错误的函数中调用了下一页方法。我更正了。
    • 不错。如果您得到了您想要的帮助,请将其标记为正确答案,以帮助其他最终在这里寻找相同答案的人。
    猜你喜欢
    • 2021-06-14
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2013-03-31
    相关资源
    最近更新 更多