如何在Scrapy CrawlSpider中访问特定的start_url?

pem*_*ahl 6 python django scrapy

我正在使用Scrapy,特别是Scrapy的CrawlSpider类来抓取包含某些关键字的网页链接.我有一个很长的start_urls列表,它从一个连接到Django项目的SQLite数据库中获取它的条目.我想在此数据库中保存已删除的Web链接.

我有两个Django模型,一个用于开始网址http://example.com,一个用于刮网等链接http://example.com/website1,http://example.com/website2等等.所有抓取的网页链接都是start_urls列表中其中一个开始网址的子网站.

Web链接模型与起始URL模型具有多对一关系,即Web链接模型具有到开始URL模型的外键.为了妥善保存我刮的网页链接到数据库中,我需要告诉CrawlSpiderparse_item(),其起始URL刮下网站链接属于方法.我怎样才能做到这一点?Scrapy的DjangoItem类在这方面没有帮助,因为我仍然必须明确定义使用的启动URL.

换句话说,如何将当前使用的起始URL传递给parse_item()方法,以便我可以将其与适当的已删除Web链接一起保存到数据库中?有任何想法吗?提前致谢!

war*_*iuc 8

默认情况下,您无法访问原始启动网址.

但您可以覆盖make_requests_from_url方法并将启动URL放入meta.然后在解析中你可以从那里提取它(如果你在后面的请求中产生了解析方法,不要忘记在它们中转发那个起始网址).


我没有CrawlSpider和我合作过,也许Maxim建议你会为你工作,但请记住,response.url在可能的重定向后有网址.

这是我将如何做的一个例子,但它只是一个例子(取自scrapy教程)并且未经过测试:

class MySpider(CrawlSpider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com']

    rules = (
        # Extract links matching 'category.php' (but not matching 'subsection.php')
        # and follow links from them (since no callback means follow=True by default).
        Rule(SgmlLinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),

        # Extract links matching 'item.php' and parse them with the spider's method parse_item
        Rule(SgmlLinkExtractor(allow=('item\.php', )), callback='parse_item'),
    )

    def parse(self, response): # When writing crawl spider rules, avoid using parse as callback, since the CrawlSpider uses the parse method itself to implement its logic. So if you override the parse method, the crawl spider will no longer work.
        for request_or_item in CrawlSpider.parse(self, response):
            if isinstance(request_or_item, Request):
                request_or_item = request_or_item.replace(meta = {'start_url': response.meta['start_url']})
            yield request_or_item

    def make_requests_from_url(self, url):
        """A method that receives a URL and returns a Request object (or a list of Request objects) to scrape. 
        This method is used to construct the initial requests in the start_requests() method, 
        and is typically used to convert urls to requests.
        """
        return Request(url, dont_filter=True, meta = {'start_url': url})

    def parse_item(self, response):
        self.log('Hi, this is an item page! %s' % response.url)

        hxs = HtmlXPathSelector(response)
        item = Item()
        item['id'] = hxs.select('//td[@id="item_id"]/text()').re(r'ID: (\d+)')
        item['name'] = hxs.select('//td[@id="item_name"]/text()').extract()
        item['description'] = hxs.select('//td[@id="item_description"]/text()').extract()
        item['start_url'] = response.meta['start_url']
        return item
Run Code Online (Sandbox Code Playgroud)

问你是否有任何问题.顺便说一句,使用的PyDev的"转到定义"功能,您可以看到scrapy来源,并了解哪些参数Request,make_requests_from_url以及其他类和方法的期望.进入代码可以帮助并节省您的时间,尽管一开始可能看起来很困难.