【问题标题】:Scrapy - LinkExtractor & setting DEPTH_LIMIT not working?Scrapy - LinkExtractor 和设置 DEPTH_LIMIT 不起作用?
【发布时间】:2018-06-28 23:44:15
【问题描述】:

所以我传递了一个start_url,它是一页新闻文章(例如cnn.com)。但是,我只想提取新闻文章本身,我不想关注文章页面上的任何链接。为此,我使用具有以下规则的CrawlSpider

rules = (
    Rule(LinkExtractor(allow=('regexToMatchArticleUrls',),
    deny=('someDenyUrls')), callback='parse_article_page'),
)

def parse_article_page(self,response): 
    #extracts the title, date, body, etc of article 

我已启用scrapy.spidermiddlewares.depth.DepthMiddleware 并设置DEPTH_LIMIT = 1

但是,我仍然会从恰好与 regexToMatchArticleUrls 匹配的各个文章页面抓取链接,因为它们是指向同一网站其他部分的链接(我无法使正则表达式更具限制性)。

但是,当DEPTH_LIMIT=1 出现时,为什么这些链接会被抓取?是不是因为DEPTH_LIMIT 重置了从LinkExtractor 提取的每个链接,即。文章页面网址?有没有办法让DEPTH_LIMIT 工作或扩展DepthMiddleware 以不抓取文章页面上的链接?谢谢!

【问题讨论】:

    标签: python web-scraping scrapy scrapy-spider


    【解决方案1】:

    为了让 DepthMiddleware 正常工作,需要将元属性从一个请求传递到另一个请求,否则,depth 将在每个新请求后设置为 0。

    不幸的是,默认情况下,CrawlSpider 不会在一个请求到下一个请求中保留此元属性。

    这可以通过使用蜘蛛中间件 (middlewares.py) 来解决:

    from scrapy import Request
    
    
    class StickyDepthSpiderMiddleware:
    
        def process_spider_output(self, response, result, spider):
            key_found = response.meta.get('depth', None)
            for x in result:
                if isinstance(x, Request) and key_found is not None:
                    x.meta.setdefault('depth', key_found)
                yield x
    

    另外,不要忘记在您的 settings.py 中包含此中间件:

    SPIDER_MIDDLEWARES = { '{your_project_name}.middlewares.StickyDepthSpiderMiddleware' : 100 }
    

    【讨论】:

    • 哦,我明白了..谢谢!但是self.key 在这里指的是什么?
    • 我也根据this尝试了x.meta.setdefault('depth', key_found),但不知道为什么不起作用?
    • 你好,self.key 应该是depth,我的错。您能否粘贴您的日志运行以查看可能发生的情况?
    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 2023-03-11
    相关资源
    最近更新 更多