Подтвердить что ты не робот

Проникающая память

У моего паука серьезная утечка памяти. Через 15 минут запустите его память 5gb, и scrapy сообщает (используя prefs()), что 900k запрашивает объекты и все. Что может быть причиной такого большого количества объектов живых запросов? Запрос только поднимается и не опускается. Все остальные объекты близки к нулю.

Мой паук выглядит следующим образом:

class ExternalLinkSpider(CrawlSpider):
  name = 'external_link_spider'
  allowed_domains = ['']
  start_urls = ['']

  rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),)

  def parse_obj(self, response):
    if not isinstance(response, HtmlResponse):
        return
    for link in LxmlLinkExtractor(allow=(), deny=self.allowed_domains).extract_links(response):
        if not link.nofollow:
            yield LinkCrawlItem(domain=link.url)

Здесь вывод prefs()

HtmlResponse                        2   oldest: 0s ago 
ExternalLinkSpider                  1   oldest: 3285s ago
LinkCrawlItem                       2   oldest: 0s ago
Request                        1663405   oldest: 3284s ago

Память на 100 тыс. царапаемых страниц может достигать отметки в 40 гб на некоторых сайтах (например, на сайте victorinox.com он достигает 35 ГБ памяти со скоростью 100 тыс. скрещенных страниц). На других его гораздо меньше.

UPD.

Objgraph для самого старого запроса после некоторого времени запуска

введите описание изображения здесь

4b9b3361

Ответ 1

Есть несколько возможных проблем, которые я вижу сразу.

Прежде чем начать, я хотел бы упомянуть, что prefs() не показывает количество запросов в очереди, оно показывает количество объектов Request(), которые являются живыми. Он может ссылаться на объект запроса и поддерживать его, даже если он больше не загружается в очередь.

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

С самого начала, я бы спросил: вы используете куки? Если нет, сайты, которые передают идентификатор сеанса в виде переменной GET, будут генерировать новый идентификатор сеанса для каждого посещения страницы. Вы по существу продолжаете поочередно повторять одни и те же страницы. Например, у victorinox.com будет что-то вроде "jsessionid = 18537CBA2F198E3C1A5C9EE17B6C63AD" в строке URL-адреса, с изменением идентификатора для каждой новой загрузки страницы.

Во-вторых, вы можете поразить пауков-пауков. То есть, страница, которая просто перезагружается, с новым бесконечным количеством ссылок. Подумайте о календаре со ссылкой на "следующий месяц" и "предыдущий месяц". Тем не менее, я не вижу ничего на сайте victorinox.com.

В-третьих, из предоставленного кода ваш Паук не ограничен каким-либо конкретным доменом. Он будет извлекать каждую найденную ссылку на каждой странице, используя parse_obj для каждого из них. На главной странице сайта victorinox.com есть ссылка на http://www.youtube.com/victorinoxswissarmy. Это, в свою очередь, заполнит ваши запросы тоннами ссылок на YouTube.

Вам нужно устранить неполадки, чтобы узнать, что именно происходит.

Некоторые стратегии, которые вы можете использовать:

  • Создайте новое Middleware Downloader и зарегистрируйте все ваши запросы (в файл или базу данных). Просмотрите запросы на нечетное поведение.
  • Ограничьте глубину, чтобы не допустить бесконечного продолжения отверстия кролика.
  • Ограничьте домен, чтобы проверить, все ли проблема.

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