我正在使用视频网站来频繁访问内容。我正在考虑使用scrapy来执行我的蜘蛛侠,但我不确定如何删除过期的项目。
检测项目是否过期的策略是:
请告诉我如何在scrapy中删除过期的物品。我将通过django将我的scrapy项目存储在mysql DB中。
我找到了一个有效的解决方案,但仍然可能不是最佳解决方案。我在每个同步的视频上都保留了“found_in_last_scan”标志。当蜘蛛启动时,它将所有标志设置为False。完成后,它会删除仍将标志设置为False的视频。我通过附加到signals.spider_opened
和signals.spider_closed
来做到这一点。请确认这是一个有效的策略,并且没有任何问题。
答案 0 :(得分:4)
我没有测试过这个!
我必须承认我没有尝试过在Scrapy中使用Django模型,但是这里有:
我想象的最简单的方法是通过扩展XMLFeedSpider(从scrapy文档复制,然后修改)为deleted.rss
文件创建一个新的蜘蛛。我建议你创建一个新的蜘蛛,因为以下逻辑很少与用于抓取网站的逻辑有关:
from scrapy import log
from scrapy.contrib.spiders import XMLFeedSpider
from myproject.items import DeletedUrlItem
class MySpider(XMLFeedSpider):
domain_name = 'example.com'
start_urls = ['http://www.example.com/deleted.rss']
iterator = 'iternodes' # This is actually unnecesary, since it's the default value
itertag = 'item'
def parse_node(self, response, url):
url['url'] = node.select('#path/to/url').extract()
return url # return an Item
SPIDER = MySpider()
这是不你正在使用的工作蜘蛛,但是IIRC的RSS文件是纯XML。我不确定deleted.rss
是怎样的,但我相信你可以弄清楚如何从XML中提取URL。现在,这个示例导入myproject.items.DeletedUrlItem
,这只是本例中的一个字符串,但您需要使用类似下面的代码创建DeletedUrlItem:
您需要创建DeletedUrlItem:
class DeletedUrlItem(Item):
url = Field()
而不是保存delete the items using Django's Model API中的Scrapy's ItemPipeline - 我假设您使用的是DjangoItem:
# we raise a DropItem exception so Scrapy
# doesn't try to process the item any further
from scrapy.core.exceptions import DropItem
# import your model
import django.Model.yourModel
class DeleteUrlPipeline(item):
def process_item(self, spider, item):
if item['url']:
delete_item = yourModel.objects.get(url=item['url'])
delete_item.delete() # actually delete the item!
raise DropItem("Deleted: %s" % item)
注意delete_item.delete()
。
我知道这个答案可能包含错误,它是由内存写的:-)但是如果你有评论或者无法解决这个问题我肯定会更新。
答案 1 :(得分:0)
如果您有一个HTTP URL,您怀疑它可能根本不再有效(因为您在“已删除”的Feed中找到它,或者仅因为您暂时没有检查它),最简单,最快检查的方法是发送该URL的HTTP HEAD
请求。在Python中,最好使用标准库的httplib模块:使用HTTPConnection向感兴趣的主机创建连接对象c
(如果是HTTP 1.1,则可以重复使用它多个URL具有更好的性能和更低的systrem负载),然后执行一个(或更多,如果可行,即如果正在使用HTTP 1.1)调用c
的{{3}}方法,第一个参数'HEAD' ,第二个参数是您正在检查的URL(当然没有主机部分; - )。
在每次request
之后,您致电c.getresponse()
以获取request对象,其status
属性会告诉您该网址是否仍然有效。
是的,它有点低级别,但正是由于这个原因,它可以让你更好地优化你的任务,只需要一点点HTTP知识; - )。