Как удалить просроченные элементы из базы данных с помощью Scrapy - PullRequest
3 голосов
/ 12 января 2010

Я использую spidering видео-сайт, который часто истекает содержание. Я планирую использовать scrapy , чтобы сделать свою паутинку, но не знаю, как удалить просроченные элементы.

Стратегии, чтобы определить, истек ли срок действия элемента:

  1. Паук сайта "delete.rss".
  2. Каждые несколько дней попробуйте перезагрузить страницу содержимого и убедиться, что она по-прежнему работает.
  3. Добавьте каждую страницу в индексах содержания сайта и удалите видео, если оно не найдено.

Пожалуйста, дайте мне знать, как удалить просроченные предметы в скрапе. Я буду хранить свои записки в базе данных mysql через django.

2010-01-18 Обновление

Я нашел решение, которое работает, но все еще не может быть оптимальным. Я поддерживаю флаг "found_in_last_scan" в каждом синхронизируемом видео. Когда паук запускается, он устанавливает все флаги в False. Когда он заканчивается, он удаляет видео, для которых все еще установлен флаг False. Я сделал это, подключившись к signals.spider_opened и signals.spider_closed. Пожалуйста, подтвердите, что это правильная стратегия, и с ней нет проблем.

Ответы [ 2 ]

4 голосов
/ 18 января 2010

Я не проверял это!
Я должен признаться, что я не пытался использовать модели Джанго в Scrapy, но здесь идет:

Самым простым способом, который я представляю, было бы создание нового паука для файла deleted.rss путем расширения XMLFeedSpider ( Скопировано из документации по scrapy, затем изменено ). Я предлагаю вам создать нового паука, потому что очень мало следующей логики связано с логикой, используемой для очистки сайта:

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, но я уверен, что вы можете понять, как извлечь URL из XML. Теперь этот пример импортирует myproject.items.DeletedUrlItem, который является просто строкой в ​​этом примере, но вам нужно создать DeletedUrlItem, используя что-то вроде кода ниже:

Вам необходимо создать элемент DeletedUrlItem:

class DeletedUrlItem(Item):
    url = Field()

Вместо сохранения вы удаляете элементы с помощью API модели Django в ItemPipeline Scrapy - я предполагаю, что вы используете 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().


Я знаю, что этот ответ может содержать ошибки, он написан по памяти :-), но я обязательно обновлю, если у вас есть комментарии или вы не можете понять это.

0 голосов
/ 18 января 2010

Если у вас есть HTTP-URL, который, как вы подозреваете, может больше не быть действительным (потому что вы нашли его в «удаленном» фиде или просто потому, что вы его еще не проверяли), самый простой и быстрый Чтобы проверить это, нужно отправить запрос HTTP HEAD для этого URL. В Python это лучше всего сделать с помощью модуля httplib стандартной библиотеки: сделать объект подключения c к интересующему хосту с помощью HTTPConnection (если HTTP 1.1, его можно использовать повторно чтобы проверить несколько URL-адресов с лучшей производительностью и меньшей загрузкой системы, затем выполните один (или более, если возможно, т. е. если используется HTTP 1.1) вызов метода c 's request , первый аргумент' HEAD ', второй аргумент URL, который вы проверяете (конечно, без части хоста; -).

После каждого request вы вызываете c.getresponse(), чтобы получить HTTPResponse объект, чей атрибут status сообщит вам, если URL все еще действителен.

Да, это немного низкоуровневый, но именно по этой причине он позволяет вам намного лучше оптимизировать свою задачу, лишь немного зная HTTP; -).

...