指向本地缓存而不是执行正常的spidering进程

2024-09-17 19:44:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用管道将Scrapy crawls中的文档缓存到数据库中,这样,如果我更改了项解析逻辑,就可以重新分析它们,而不必再次访问服务器。在

从正常的缓存中抓取的最好方法是什么?在

我喜欢scrapy对CSS和XPath选择器的支持,否则我只需要用lxml解析器分别访问数据库。在

有一段时间,我根本没有缓存文档,也没有以正常的方式使用scray(动态解析项目),但我发现更改项目逻辑需要耗费大量时间和资源。取而代之的是,我现在正在缓存文档体和项解析,并且我希望可以选择让Scrapy迭代数据库中的文档,而不是爬行目标URL。在

我该如何修改Scrapy,让我可以选择向它传递一组文档,然后对它们进行单独的解析,就好像它刚刚将它们从web上拉下来一样?在


Tags: 项目方法文档服务器数据库解析器管道选择器
1条回答
网友
1楼 · 发布于 2024-09-17 19:44:40

我认为custom Downloader Middleware是个好方法。其思想是让这个中间件直接从数据库返回源代码,而不让Scrapy发出任何HTTP请求。在

示例实现(未经测试,肯定需要错误处理):

import re

import MySQLdb
from scrapy.http import Response    
from scrapy.exceptions import IgnoreRequest
from scrapy import log
from scrapy.conf import settings


class CustomDownloaderMiddleware(object):
   def __init__(self, *args, **kwargs):
        super(CustomDownloaderMiddleware, self).__init__(*args, **kwargs)

        self.connection = MySQLdb.connect(**settings.DATABASE)
        self.cursor = self.connection.cursor()

   def process_request(self, request, spider):
       # extracting product id from a url
       product_id = re.search(request.url, r"(\d+)$").group(1)

       # getting cached source code from the database by product id
       self.cursor.execute("""
           SELECT
               source_code
           FROM
               products
           WHERE
               product_id = %s
       """, product_id)

       source_code = self.cursor.fetchone()[0]

       # making HTTP response instance without actually hitting the web-site
       return Response(url=request.url, body=source_code)

别忘了activate the middleware。在

相关问题 更多 >