我使用管道将Scrapy中的文档缓存到数据库中,这样我就可以重新解析它们,如果我更改项目解析逻辑而不必再次点击服务器。
从缓存中获取Scrapy进程而不是尝试执行正常爬网的最佳方法是什么?
我喜欢scrapy对CSS和XPath选择器的支持,否则我只是用lxml解析器单独命中数据库。
有一段时间,我根本没有缓存文档并以正常方式使用Scrapy - 动态解析项目 - 但我发现更改项目逻辑需要时间和资源密集重新抓取。相反,我现在正在缓存文档正文以及项目解析,我想让Scrapy从数据库迭代这些文档而不是抓取目标URL。
我如何修改Scrapy,让我可以选择将一组文档传递给它,然后单独解析它们,就好像它刚刚将它从Web上拉下来一样?
答案 0 :(得分:1)
我认为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)