python - Scrapy - LinkExtractor 和设置 DEPTH_LIMIT 不起作用?

标签 python web-scraping scrapy

因此,我传入一个 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 时这些链接会被抓取呢?是否因为从 LinkExtractor 提取的每个链接都会重置 DEPTH_LIMIT,即。文章页面网址?有没有办法让 DEPTH_LIMIT 工作或扩展 DepthMiddleware 以不抓取文章页面上的链接?谢谢!

最佳答案

为了使 DepthMiddleware 正常工作,元属性需要从一个请求传递到另一个请求,否则,深度 在每个新请求后将被设置为 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 }

关于python - Scrapy - LinkExtractor 和设置 DEPTH_LIMIT 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51092507/

相关文章:

python - MySQLdb和mysqlconnector的区别

java - 使用 Jsoup 提取 HTML 数据

python - Scrapy并发策略

python - 除了使用 BeautifulSoup 和 Scrapy 之外,有没有其他方法可以抓取不可抓取的网站,因为它们不起作用?

callback - 设置 process_request 和回调参数时,Scrapy 规则不起作用

python - pd.merge_asof 每个时间段有多个匹配项?

python - django 1.5.4 中的 STATIC_URL 问题

C#:使用 Python.Runtime 未找到

javascript - 如何使用 BeautifulSoup 抓取由 javascript 生成的数据?

python - 通过命令行调用scrapy的自定义导出器