我正在使用Scrapy抓取几个可能共享冗余信息的网站.
对于我抓取的每个页面,我将页面的URL,标题和html代码存储到mongoDB中.我想避免数据库中的重复,因此,我实现了一个管道,以检查是否已经存储了类似的项目.在这种情况下,我提出DropItem异常.
我的问题是,每当我通过raison DropItem异常删除项目时,Scrapy会将项目的全部内容显示在日志(stdout或文件)中.由于我正在提取每个已删除页面的整个HTML代码,因此在丢弃的情况下,整个HTML代码将显示在日志中.
如果没有显示内容,我怎么能默默地删除项目?
感谢您的时间!
class DatabaseStorage(object):
""" Pipeline in charge of database storage.
The 'whole' item (with HTML and text) will be stored in mongoDB.
"""
def __init__(self):
self.mongo = MongoConnector().collection
def process_item(self, item, spider):
""" Method in charge of item valdation and processing. """
if item['html'] and item['title'] and item['url']:
# insert item in mongo if not already present
if self.mongo.find_one({'title': item['title']}):
raise DropItem('Item already in db')
else:
self.mongo.insert(dict(item))
log.msg("Item %s scraped" % item['title'],
level=log.INFO, spider=spider)
else:
raise DropItem('Missing information on item %s' % (
'scraped from ' + item.get('url')
or item.get('title')))
return item
Run Code Online (Sandbox Code Playgroud)
小智 21
执行此操作的正确方法是为项目实现自定义LogFormatter,并更改已删除项目的日志记录级别.
例:
from scrapy import log
from scrapy import logformatter
class PoliteLogFormatter(logformatter.LogFormatter):
def dropped(self, item, exception, response, spider):
return {
'level': log.DEBUG,
'format': logformatter.DROPPEDFMT,
'exception': exception,
'item': item,
}
Run Code Online (Sandbox Code Playgroud)
然后在您的设置文件中,例如:
LOG_FORMATTER = 'apps.crawler.spiders.PoliteLogFormatter'
Run Code Online (Sandbox Code Playgroud)
我运气不好只返回"无",这在未来的管道中引起了异常.
mir*_*val 16
在最近的Scrapy版本中,这已经有所改变.我从@jimmytheleaf复制了代码并修复它以使用最近的Scrapy:
import logging
from scrapy import logformatter
class PoliteLogFormatter(logformatter.LogFormatter):
def dropped(self, item, exception, response, spider):
return {
'level': logging.INFO,
'msg': logformatter.DROPPEDMSG,
'args': {
'exception': exception,
'item': item,
}
}
Run Code Online (Sandbox Code Playgroud)
Bal*_*rol 11
好的,我甚至在发布问题之前就找到了答案.我仍然认为答案对于遇到同样问题的人来说可能是有价值的.
DropItem您只需返回None值,而不是使用异常删除对象:
def process_item(self, item, spider):
""" Method in charge of item valdation and processing. """
if item['html'] and item['title'] and item['url']:
# insert item in mongo if not already present
if self.mongo.find_one({'url': item['url']}):
return
else:
self.mongo.insert(dict(item))
log.msg("Item %s scraped" % item['title'],
level=log.INFO, spider=spider)
else:
raise DropItem('Missing information on item %s' % (
'scraped from ' + item.get('url')
or item.get('title')))
return item
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5199 次 |
| 最近记录: |