因此,我传入的是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
而不抓取文章页面上的链接?谢谢!
答案 0 :(得分:1)
为了使DepthMiddleware正常工作,需要将meta属性从一个请求传递到另一个请求,否则,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 }