2015-08-21 3 views
2
import scrapy 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 
from scrapy.selector import HtmlXPathSelector 
from scrapy.http import Request 
from Erowid.items import ErowidItem 
import os 

class ExperiencesSpider(CrawlSpider): 
    name = "experiences" 
    allowed_domains = ["www.erowid.org"] 
    start_urls = ['https://www.erowid.org/experiences/exp_list.shtml'] 

    rules = [Rule(LinkExtractor(allow =('subs/exp_[a-zA-Z]+.shtml')),callback='parse_item', follow = True) 

    Rule(LinkExtractor(allow =('subs/exp_[a-zA-Z]+.shtml')), follow = True)  

    ] 

    def parse_item(self, response): 
     filename = str(response.url)[44:-6] 
     selectors = response.css('table') 
     if not os.path.exists('drugs-%s' % (filename)): ##Make the file 
      os.makedirs('drugs-%s' % (filename)) 
     list_of_experience = selectors.xpath('//table[@class="exp-cat-table"]/tr/td/a/@href').extract() 

     for item in list_of_experience: 
      request_url = str(item) 
      Request(url="http://www.erowid.org" + request_url, callback = 'request_experience') 
      def request_experience(self, response): 
       selectors = response.css('div') 
       for selector in selectors: 
        experience = ErowidItem() 
        experience['Author'] = selector.xpath('//div[@class="author"]/a/text()').extract() 
        experience['Title'] = selector.xpath('//div[@class="title"]/text()').extract() 
        experience['Substance'] = selector.xpath('//div[@class="substance"]/text()').extract() 
        experience['Text'] = selector.xpath("//div[@class = 'report-text-surround']/text()").extract() 

        title = str(experience['Substance']) + " "+ str(experience['Title']) 
        with open(os.path.join('drugs-%s' % (filename), title),"a") as fid: 
         fid.write(str(experience) + "\n") 

Я пытаюсь использовать Scrapy, чтобы очистить данные из Erowid и я пытаюсь форматировать данные таким образом, что для каждого вещества, у меня есть файл с именем в виде «вещество - название опыта ».Scrapy - Ошибка в написании файлов

Мои правила заставляют моего паука проползать через список сайтов, включая https://www.erowid.org/experiences/subs/exp_Acacia_confusa.shtml. Затем я получаю все ссылки, которые переходят к опыту, и на этот раз поставил это через второй запрос, нацеленный на сбор данных из опыта.

Я намеревался хранить данные в указанном выше формате, который является «веществом - названием опыта». Для каждого вещества я хочу создать каталог, полный файлов с этой страницы.

Мой код, однако, делает каталоги, но не записывает файлы, которые я хочу.

В чем причина этой ошибки?

ответ

0

По documentation of scrapy.http.Request -

обратного вызова (вызываемая) - функция, которая будет вызвана с ответом этого запроса (один раз его загружены) в качестве первого параметра.

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

Пример -

import scrapy 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 
from scrapy.selector import HtmlXPathSelector 
from scrapy.http import Request 
from Erowid.items import ErowidItem 
import os 

class ExperiencesSpider(CrawlSpider): 
    name = "experiences" 
    allowed_domains = ["www.erowid.org"] 
    start_urls = ['https://www.erowid.org/experiences/exp_list.shtml'] 

    rules = [Rule(LinkExtractor(allow =('subs/exp_[a-zA-Z]+.shtml')),callback='parse_item', follow = True) 

    Rule(LinkExtractor(allow =('subs/exp_[a-zA-Z]+.shtml')), follow = True)  

    ] 

    def request_experience(self, response): 
     selectors = response.css('div') 
     for selector in selectors: 
      experience = ErowidItem() 
      experience['Author'] = selector.xpath('//div[@class="author"]/a/text()').extract() 
      experience['Title'] = selector.xpath('//div[@class="title"]/text()').extract() 
      experience['Substance'] = selector.xpath('//div[@class="substance"]/text()').extract() 
      experience['Text'] = selector.xpath("//div[@class = 'report-text-surround']/text()").extract() 

      title = str(experience['Substance']) + " "+ str(experience['Title']) 
      with open(os.path.join('drugs-%s' % (self.filename), title),"a") as fid: 
       fid.write(str(experience) + "\n") 

    def parse_item(self, response): 
     self.filename = str(response.url)[44:-6] 
     selectors = response.css('table') 
     if not os.path.exists('drugs-%s' % (self.filename)): ##Make the file 
      os.makedirs('drugs-%s' % (self.filename)) 
     list_of_experience = selectors.xpath('//table[@class="exp-cat-table"]/tr/td/a/@href').extract() 

     for item in list_of_experience: 
      request_url = str(item) 
      Request(url="http://www.erowid.org" + request_url, callback = self.request_experience) 
+0

Я пытался что-то подобное раньше, но проблема в том, что теперь переменная имя файла будет определено в request_experience и она по-прежнему не будет работать. –

+0

вы можете установить имя файла для себя и получить доступ к нему оттуда. Обновление моего кода для этого. –

+0

По-моему, это не работает для меня. Все, что он делает, это создавать каталоги, но не получает файлы. –

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