Как сделать петлю на уроке скрапинга? - PullRequest
0 голосов
/ 30 апреля 2019

Я очищаю сайт. Но у меня есть проблема. Я создал класс и переменную и дал ей ссылку для очистки данных. Но на сайте есть много категорий на одной странице. Означает, что названия стран перечислены в алфавитном порядке A, B upto Z. Я сделал цикл, чтобы просто ввести первый алфавит страны, начиная с A, B upto Z, чтобы я не мог повторять ссылки снова и снова. Но это не работает. Он просто дает мне названия стран, которые находятся в конце списка переменных eleventh_category. Если список заканчивается буквой C, я получу только названия стран, начиная с C, а не B и A. Надеюсь, вы поняли ..

class DmozSpiderSpider(scrapy.Spider):
    name = 'Dmoz'
    start_urls = ['http://dmoz-odp.org/']
    eleventh_category = ['A','B','C']
    for again in eleventh_category:
        save = f'http://dmoz-odp.org/Regional/{again}/'

    def parse(self, response):
        # collect data on page
        items = {
        'Navbar': response.css('#main-nav a::text').extract(),
        'Category_names': response.css('.top-cat a::text').extract(),
        'Subcategories': response.css('.sub-cat a::text').extract(),
        # this is eleventh_category
        'Eleventh_category': self.save
        }

    # save and call request to another page
    dct = [(self.save, self.alpha_country)]
    for page, callback in dct:
        yield response.follow(page, callback, meta={'items': items})

    def find_items(self, response, names, finder):
        items = response.meta['items']
        for name, find in zip(names.values(), finder.values()):
            items[name] = response.css(find).extract()
            yield items

    def alpha_country(self, response):
        items = response.meta['items']
        names = {'name1': 'Countries'}
        finder = {'finder1': '.browse-node::text'}
        for name, find in zip(names.values(), finder.values()):
            items[name] = [i.strip() for i in response.css(find).extract() if i.strip()]
            yield items

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Я заблудился в вашей логике о переменных вне функций (или у вас есть проблемы с отступами), но проверьте это решение:

import scrapy

class DmozSpiderSpider(scrapy.Spider):
    name = 'Dmoz'
    start_urls = ['http://dmoz-odp.org/']

    def parse(self, response):
        eleventh_category = ['A', 'B', 'C']
        for again in eleventh_category:
            save = 'http://dmoz-odp.org/Regional/{}/'.format(again)
            items = {
                'Navbar': response.css('#main-nav a::text').extract(),
                'Category_names': response.css('.top-cat a::text').extract(),
                'Subcategories': response.css('.sub-cat a::text').extract(),
                # this is eleventh_category
                'Eleventh_category': save,
            }
            yield response.follow(save, self.alpha_country, meta={'items': items})

    def find_items(self, response, names, finder):
        items = response.meta['items']
        for name, find in zip(names.values(), finder.values()):
            items[name] = response.css(find).extract()
            yield items

    def alpha_country(self, response):
        items = response.meta['items']
        names = {'name1': 'Countries'}
        finder = {'finder1': '.browse-node::text'}
        for name, find in zip(names.values(), finder.values()):
            items[name] = [i.strip() for i in response.css(find).extract() if i.strip()]
            yield items

Здесь у вас есть все логики и вызовы внутри функции parse, которыегораздо проще и удобочитаемее.

0 голосов
/ 30 апреля 2019

Если список заканчивается буквой C, я получу только имена страны, начиная с C

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

Вы можете поместить цикл в метод parse:

class DmozSpiderSpider(scrapy.Spider):
    name = 'Dmoz'
    start_urls = ['http://dmoz-odp.org/']
    eleventh_category = ['A','B','C']

    def parse(self, response):    
        for again in self.eleventh_category:
            save = f'http://dmoz-odp.org/Regional/{again}/'
            items = {
                'Navbar': response.css('#main-nav a::text').extract(),
                'Category_names': response.css('.top-cat a::text').extract(),
                'Subcategories': response.css('.sub-cat a::text').extract(),
                # this is eleventh_category
                'Eleventh_category': save
            }
            # save and call request to another page
            dct = [(save, self.alpha_country)]
            for page, callback in dct:
                yield response.follow(page, callback, meta={'items': items})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...