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

标签 python django scrapy

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

我有两个 Django 模型,一个用于启动 url,例如 http://example.com一个用于抓取的网络链接,例如 http://example.com/website1 , http://example.com/website2等等。所有抓取的 Web 链接都是 start_urls 中起始网址之一的子站点。列表。

网络链接模型与起始 url 模型具有多对一关系,即网络链接模型具有指向起始 url 模型的外键。为了将我抓取的 Web 链接正确保存到数据库中,我需要告诉 CrawlSpiderparse_item()抓取的 web 链接所属的开始 url 的方法。我怎样才能做到这一点? Scrapy的DjangoItem class 在这方面没有帮助,因为我仍然必须明确定义使用的起始 url。

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

最佳答案

默认情况下,您无法访问原始起始网址。

但是你可以覆盖make_requests_from_url方法并将开始 url 放入 meta .然后在解析中,您可以从那里提取它(如果您在该解析方法中产生后续请求,请不要忘记在其中转发该起始 url)。


我没有使用过 CrawlSpider,也许 Maxim 的建议对你有用,但请记住 response.url 有可能重定向后的 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

有问题就问。顺便说一句,使用 PyDev 的“转到定义”功能,您可以查看 scrapy 源并了解 Requestmake_requests_from_url 和其他类和方法期望的参数。深入了解代码有助于并节省您的时间,尽管一开始可能看起来很困难。

关于python - 如何访问 Scrapy CrawlSpider 中的特定 start_url?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10598691/

相关文章:

python - django 中的关系数据库以弹出形式

javascript - 如何在传入的 http 请求 header 中添加授权 token

django - Docker和Django manage.py

python - 有没有一种方法可以在不使用中间件的情况下使用 scrapy 代理?

python - 使用 Python Scrapy 遍历站点

python - 什么是 PyCharm "simplify chained comparison"

python - 如果使用 groupby 方法满足另一列中的条件,则使用多列进行条件过滤

python - 启动 scrapy shell 时如何禁用 robots.txt?

python - 如何将 Pandas 数据框行快速转换为有序字典

python - Django Channels 或 Tornado 用于基于套接字的连接