2015-12-28 5 views
3

Я пытаюсь отказаться от сайта с помощью scrapy.Сканирование сайта рекурсивно с помощью scrapy

Это код, который я написал до сих пор основан на http://thuongnh.com/building-a-web-crawler-with-scrapy/ (исходного код не работаю вообще, поэтому я попытался восстановить его)

from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 
from scrapy.spiders    import Spider 
from scrapy.selector   import HtmlXPathSelector 
from nettuts.items   import NettutsItem 
from scrapy.http   import Request 
from scrapy.linkextractors import LinkExtractor 


class MySpider(Spider): 
    name = "nettuts" 
    allowed_domains = ["net.tutsplus.com"] 
    start_urls = ["http://code.tutsplus.com/posts?"] 
    rules = [Rule(LinkExtractor(allow = ('')), callback = 'parse', follow = True)] 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     item = [] 

     titles = hxs.xpath('//li[@class="posts__post"]/a/text()').extract() 
     for title in titles: 
      item    = NettutsItem() 
      item["title"]  = title 
      yield item 
     return 

Проблемы заключается в том, что гусеничный идет на стартовой страницу, но делает после этого не ломайте страницы.

+0

примера использования этого класса? – Caridorc

+1

@Caridorc это Scrapy, о котором мы говорим. У него есть scrapy cli с разными командами, и он знает, как забрать scrapy spiders в проекте и запустить их. Благодарю. – alecxe

ответ

2

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

Вместо этого используйте CrawlSpider:

class MySpider(CrawlSpider): 
+0

Большое спасибо за ваш ответ, это очень полезно. У меня все еще есть проблемы. Я думаю, что строка «правила» неверна. Я пытаюсь вставить разные значения, но он не работает. Могу ли я попросить дополнительную подсказку? – Macro

+0

Первая страница для сканирования: http://code.tutsplus.com/posts?page=1, следующая страница: http://code.tutsplus.com/posts?page=2 и т. Д. – Macro

8

После может быть хорошей идеей, чтобы начать с:

Там может быть два случая использования для "обхода сайта рекурсивно с помощью Scrapy.

A). Мы просто хотим переместиться через веб-сайт, используя, скажем, кнопки разбиения на страницы таблицы и выборку данных. Это относительно прямо.

class TrainSpider(scrapy.Spider): 
    name = "trip" 
    start_urls = ['somewebsite'] 
    def parse(self, response): 
     ''' do something with this parser ''' 
     next_page = response.xpath("//a[@class='next_page']/@href").extract_first() 
     if next_page is not None: 
      next_page = response.urljoin(next_page) 
      yield scrapy.Request(next_page, callback=self.parse)` 

Соблюдайте последние 4 строки. Здесь

  1. Мы получаем следующую страницу ссылки следующей страницы xpath из кнопки «Следующая».
  2. Условие if проверяет, если это не конец страницы.
  3. Присоединитесь к этой ссылке (которую мы получили на шаге 1) с основным URL-адресом, используя urljoin
  4. Рекурсивный вызов метода обратного вызова 'parse'.

B) Мы не только хотим перемещаться по страницам, но также хотим извлечь данные из одной или нескольких ссылок на этой странице.

class StationDetailSpider(CrawlSpider): 
    name = 'train' 
    start_urls = [someOtherWebsite] 
    rules = (
     Rule(LinkExtractor(restrict_xpaths="//a[@class='next_page']"), follow=True), 
     Rule(LinkExtractor(allow=r"/trains/\d+$"), callback='parse_trains') 
    ) 
    def parse_trains(self, response): 
     '''do your parsing here''' 

Здесь, заметим, что:

  1. Мы используем подкласс 'CrawlSpider' из '' scrapy.Spider родительского класса

  2. Мы установили на 'Правила'

    a) Первое правило просто проверяет наличие «следующей_страницы» и следует за ним.

    b) Второе правило запрашивает все ссылки на странице, которые находятся в формате, например '/ trains/12343', а затем вызывает команду parse_trains для выполнения и синтаксического анализа.

  3. Важно: Обратите внимание, что мы не хотим использовать обычный метод parse здесь, поскольку мы используем подкласс CrawlSpider. Этот класс также имеет метод «parse», поэтому мы не хотим его переопределять.Просто не забудьте назвать свой метод обратного вызова чем-то иным, чем «parse».

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