2015-12-17 6 views
0

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

Вот проблема, с которой я сейчас сталкиваюсь.

Существует, например, сайт, http://example.com/. Я хочу отказаться от некоторых данных.

Он имеет много элементов, которые URLs в форме http://example.com/item/([0-9]+), теперь я есть контрольный список действительного ([0-9]+), который имеет около индекса идентификаторов, это могло бы, кажется, простая задача, чтобы завершить все веб-страница ломает работу.

Но, структура этой миссии, как это:

  • есть много данных элемента на странице /item/. Я хочу эту информацию, этого просто достичь.
  • есть ссылки на объект, относящийся к объекту, например item owner со ссылкой /owner/, или the collections the item belongs со ссылкой /collection/ и так далее. Я хочу, чтобы все было уникальным информации об этих объектах, чего трудно достичь. Они не должны быть вложенным элемент item или слом однократным паука из-за следующей причине:
    • одногоowner имеют [1-n] элементы.
    • описание товара товар есть [1-n]owners.
    • такой же, как collection с товаром.
  • есть ссылки относятся к другой организации, связанной с элементом, например, comment с пути ссылками /comment/ или user, кто любит его с путем /user/ ссылки. Очевидно, что было бы целесообразно разделить comment или user информацию, удаленную от item и использовать ключ или index для получения сущности. Этого трудно достичь одним пауком.

Итак, я предпочитаю, чтобы начать паук, чтобы обработать список http://example.com/item/([0-9]+), а также использовать другие типы пауков справиться с item owner, collection, comment и user соответственно.

Но, проблема у меня нет списка item owner, collection, comment и user. Я мог бы пройти через все эти сущности только путем повторения веб-страницы http://example.com/item/([0-9]+).

У меня много googled, но не найдено ни одного решения, соответствующего моей проблеме. Пожалуйста, не стесняйтесь высказать свое мнение.

ответ

0

Под псевдонимом ItemSpider.

from scrapy_redis.spiders import RedisSpider 
import redis 
class ItemSpider(RedisSpider): 
    name = 'item' 
    def parse(self, response): 
     # process to get item info. 
     r = redis.Redis(...) 
     r.lpush('user:start_urls', user_link) 
     return ... 

Вот псевдо-код для UserSpider.

from scrapy_redis.spiders import RedisSpider 
class UserSpider(RedisSpider): 
    name = 'user' 
    def parse(self, response): 
     # process to get user info. 
     return ... 

А затем добавьте запись адресов в item:start_urls список в Redis.

Наконец,

scrapy crawl item 
scrapy crawl user 

Более продвинутые концепции, такие как избежать дублирующих элементов следует учитывать заранее. По меньшей мере, описанное выше решение разделило расписание на ItemSpider и UserSpider.

Я пришел в это решение из-за помощи от here, спасибо @lnxpgn.

Может ли кто-нибудь обеспечить лучшее решение? Или обеспечить лучшее решение для избежания дублирования сканирования?

0

Насколько я понимаю, вы не ищете multidomain гусеничный, потому что вы в основном отказываетесь от одного домена, не так ли? Вам даже не нужно следить за множеством разных и непредсказуемых ссылок, поскольку вы уже знаете, что вы хотите искать. Это верно?

Для этого я бы рекомендовал использовать довольно selenium (возможно, с BeautifulSoup). selenium довольно легкий, может работать без головного убора с PhantomJS, и если вы знаете структуру страницы, которая будет утилизирована, вы можете добавить гораздо больше логики и контроля по сравнению с Scrappy (ну, определенно, более легко).

Я не вижу структуры и типы конечных данных, но кажется, что они несколько иерархичны, и между ними существуют отношения. Я бы сохранил данные в dict со списками, даже если они не уникальны, а затем сбрасывают их, например. MongoDB (супер легко с pymongo, в основном 3 команды для создания соединения, а затем один, чтобы поместить его в базу данных). После сбора этого я буду заботиться о связях, фильтрации и т. Д. Обычно это намного проще (с инструментами для этой цели, такими как pandas), а затем во время утилизации.

Для вашего конкретного случая я бы сделал цикл за диапазон, который вы хотите отрезать (3M), и на каждом шаге вы будете запускать функцию для доступа к этому URL-адресу, если не 404, а затем обменивать информацию, то категория лома ... Это должны быть отдельные функции, селектора будут меняться в зависимости от структуры, использовать как можно больше CSS или XPATH, в противном случае вы можете использовать find_elements, а затем фильтровать их на основе текста или href (например, /owner/ в href из всех a).

+0

благодарит за ваш ответ. Но я бы предпочел не выбирать 'selenium' или' request' с 'BeautifulSoup', так как могут возникнуть некоторые другие проблемы, о которых я не упоминал в своем сообщении, такие как' performance', 'scheduler',' multiple proxies', 'scrap rate' и т. д., так как эти проблемы напрямую не связаны с вопросом, который я публикую. Но использование сценариев ручной работы может быть не лучшим выбором для моего желания. Все же разрешите поблагодарить вас. – myme5261314

+0

Очень приветствуется. Я понимаю, почему вы сейчас используете ломтик. Не могу больше помочь здесь ... – kotrfa

0

Большинство ваших требований, похоже, очень хорошо подходят для лечения. Вы уже сказали, что можете очистить список предметов, что является хорошим началом. Я думаю, вы говорите, что у каждого элемента есть ссылки на владельца, комментарий, пользователя. В этом случае вы получаете URL-адрес с помощью response.xpath, а затем yield Request(URL, callback=parse_owner) в качестве примера. Вы захотите связать различные скребковые данные вместе, и в этом случае вы можете добавить meta={'id': identifier} в Request(). Как сказал @kotrfa, демпинг в базу данных может быть лучше, поскольку это звучит так, как будто есть некоторая сшивка данных.

Это насколько я могу идти, учитывая предоставленную вами информацию. Более подробная информация сделает изображение более понятным для нас.

+0

Спасибо за ваш совет. Я знаю описанную вами процедуру. Я думаю, что это может закончить то, что я прошу в основном. Если будет какое-то лучшее решение, я выберу это. Причина, по которой я ожидаю лучшего решения, заключается в том, что существует несколько проблем с этим подходом. [1] дублируется обход страниц и запись базы данных (представьте, что два работника работают над двумя предметами, которые имеют один и тот же владелец одновременно). [2] график работы. В вашем решении работа для 'owner',' user' и т. Д. Не разделяется на 'item', это может включать некоторые блокировки db, которых можно было бы избежать благодаря лучшей модульности). Во всяком случае, ваша процедура работает. – myme5261314

+0

Scrapy будет посещать страницу только по умолчанию, и она может кэшировать страницы локально, если необходимо несколько посещений страницы. В settings.py установите 'HTTPCACHE_ENABLED = True'. Если вы можете дать нам несколько примеров, вы можете получить дополнительную помощь. Если мой ответ помог, не забудьте принять/отложить его;) – Steve

+0

Спасибо за вашу информацию. Я не знаком с этими деталями. Хорошо, я думаю, что у меня есть лучшее решение [здесь] (https://groups.google.com/forum/#!topic/scrapy-users/yI3bpbsWeP0). Я грубо реализую это быстро. Например, просто напишите 'ItemSpider' и' UserSpider', интегрируя 'redis' с' scrapy-redis'. Добавьте URL-адреса ** 3M ** в 'start_urls'' ItemSpider' в redis, и когда 'ItemSpider' нашел ссылку пользователя на обход, добавьте его url в' start_urls' 'UserSpider' в redis. И после того, как два кода пауков закончены, запустите двух пауков соответственно. Тогда работа выполнена. – myme5261314

Смежные вопросы