2017-09-18 3 views
3

J'ai écrit un minuscule grattoir en python scrapy pour analyser différents noms d'une page Web. La page a traversé 4 pages supplémentaires grâce à la pagination. Le nombre total de noms dans les pages est de 46, mais il est 36 noms.Scrapy ignorant le contenu de la deuxième page

Le scraper est censé ignorer le contenu des premières pages de destination, mais en utilisant l'argument parse_start_url dans mon scraper je l'ai manipulé. Cependant, le problème auquel je suis confronté en ce moment avec ce grattoir est qu'il saute étonnamment le contenu de la deuxième page et d'analyser tout le reste, je voulais dire la première page, la troisième page, la quatrième page et ainsi de suite. Pourquoi cela se passe-t-il et comment y faire face? Merci d'avance.

Voici le script que je suis en train avec:

import scrapy 

class DataokSpider(scrapy.Spider): 

    name = "dataoksp" 
    start_urls = ["https://data.ok.gov/browse?page=1&f[0]=bundle_name%3ADataset&f[1]=im_field_categories%3A4191"] 

    def parse(self, response): 
     for link in response.css('.pagination .pager-item a'): 
      new_link = link.css("::attr(href)").extract_first() 
      yield scrapy.Request(url=response.urljoin(new_link), callback=self.target_page) 

    def target_page(self, response): 
     parse_start_url = self.target_page # I used this argument to capture the content of first page 
     for titles in response.css('.title a'): 
      name = titles.css("::text").extract_first() 
      yield {'Name':name} 

Répondre

1

La solution s'avère très facile. Je l'ai déjà réparé.

import scrapy 

class DataokSpider(scrapy.Spider): 

    name = "dataoksp" 
    start_urls = ["https://data.ok.gov/browse?f[0]=bundle_name%3ADataset&f[1]=im_field_categories%3A4191"] 

    def parse(self, response): 
     for f_link in self.start_urls: 
      yield response.follow(url=f_link, callback=self.target_page) #this is line which fixes the issue 

     for link in response.css('.pagination .pager-item a'): 
      new_link = link.css("::attr(href)").extract_first() 
      yield response.follow(url=new_link, callback=self.target_page) 

    def target_page(self, response): 
     for titles in response.css('.title a'): 
      name = titles.css("::text").extract_first() 
      yield {'Name':name} 

Maintenant, il me donne tous les résultats.

0

Parce que le lien que vous indiquez dans start_urls est en fait le lien de la deuxième page. Si vous l'ouvrez, vous verrez qu'il n'y a pas de tag <a> pour la page en cours. Voilà pourquoi la page 2 n'atteint pas target_page et, par conséquent, vous devez mentionner start_urls à:

https://data.ok.gov/browse?f[0]=bundle_name%3ADataset&f[1]=im_field_categories%3A4191

Ce code devrait vous aider:

import scrapy 
from scrapy.http import Request 


class DataokspiderSpider(scrapy.Spider): 
    name = 'dataoksp' 
    allowed_domains = ['data.ok.gov'] 
    start_urls = ["https://data.ok.gov/browse?f[0]=bundle_name%3ADataset&f[1]=im_field_categories%3A4191",] 

    def parse(self, response): 
     for titles in response.css('.title a'): 
      name = titles.css("::text").extract_first() 
      yield {'Name':name} 

     next_page = response.xpath('//li[@class="pager-next"]/a/@href').extract_first() 
     if next_page: 
      yield Request("https://data.ok.gov{}".format(next_page), callback=self.parse) 

Statistiques (voir item_scraped_count):

{ 
    'downloader/request_bytes': 2094, 
    'downloader/request_count': 6, 
    'downloader/request_method_count/GET': 6, 
    'downloader/response_bytes': 45666, 
    'downloader/response_count': 6, 
    'downloader/response_status_count/200': 6, 
    'finish_reason': 'finished', 
    'finish_time': datetime.datetime(2017, 9, 19, 7, 23, 47, 801934), 
    'item_scraped_count': 46, 
    'log_count/DEBUG': 53, 
    'log_count/INFO': 7, 
    'memusage/max': 47509504, 
    'memusage/startup': 47509504, 
    'request_depth_max': 4, 
    'response_received_count': 6, 
    'scheduler/dequeued': 5, 
    'scheduler/dequeued/memory': 5, 
    'scheduler/enqueued': 5, 
    'scheduler/enqueued/memory': 5, 
    'start_time': datetime.datetime(2017, 9, 19, 7, 23, 46, 59360) 
} 
+0

Merci Andrés Pérez-Albela H., pour votre réponse. Cette solution fonctionne vraiment et avant de poster ici j'ai essayé avec elle aussi. Cependant, il y a un style intégré dans scrapy pour analyser les données de la première page qui est 'parse_start_url', je m'attendais vraiment à ce que mon script soit construit sur cette directive. Merci encore. – SIM

+0

@Topto Je suis content que ma réponse m'a aidé. Si cela répond à votre question, veuillez la définir comme réponse sélectionnée et upvote au cas où vous apprécieriez mon support. –

+0

@Topto 'parse_start_url' est pour ** CrawlSpider ** et pas pour ** Spider **. Cela dit, si vous devez le remplacer, vous devrez d'abord hériter de CrawlSpider. Cependant, CrawlSpider n'est pas nécessaire pour votre cas d'utilisation puisque vous n'avez pas besoin de règles et que le même comportement peut être reproduit avec le code que j'ai ajouté à ma réponse (avec juste Spider). –