Я пытаюсь создать паука, который собирает информацию о стартапах. Поэтому я написал Python-скрипт со scrapy, который должен получить доступ к веб-сайту и сохранить информацию в словаре. Я думаю, что код должен работать с точки зрения логики, но почему-то я не получаю никаких результатов. Мой код:

import scrapy


class StartupsSpider(scrapy.Spider):
    name = 'startups'
    #name of the spider

    allowed_domains = ['www.bmwk.de/Navigation/DE/InvestDB/INVEST-DB_Liste/investdb.html']
    #list of allowed domains

    start_urls = ['https://bmwk.de/Navigation/DE/InvestDB/INVEST-DB_Liste/investdb.html']
    #starting url

    def parse(self, response):
        
        startups = response.xpath('//*[contains(@class,"card-link-overlay")]/@href').getall()
        #parse initial start URL for the specific startup URL

        for startup in startups:
            
            absolute_url =  response.urljoin(startup)

            yield scrapy.Request(absolute_url, callback=self.parse_startup)
            #parse the actual startup information

        next_page_url = response.xpath('//*[@class ="pagination-link"]/@href').get()
        #link to next page
        
        absolute_next_page_url = response.urljoin(next_page_url)
        #go through all pages on start URL
        yield scrapy.Request(absolute_next_page_url)
    
    def parse_startup(self, response):
    #get information regarding startup
        startup_name = response.css('h1::text').get()
        startup_hompage = response.xpath('//*[@class="document-info-item"]/a/@href').get()
        startup_description = response.css('div.document-info-item::text')[16].get()
        branche = response.css('div.document-info-item::text')[4].get()
        founded = response.xpath('//*[@class="date"]/text()')[0].getall()
        employees = response.css('div.document-info-item::text')[9].get()
        capital = response.css('div.document-info-item::text')[11].get()
        applied_for_invest = response.xpath('//*[@class="date"]/text()')[1].getall()

        contact_name = response.css('p.card-title-subtitle::text').get()
        contact_phone = response.css('p.tel > span::text').get()
        contact_mail = response.xpath('//*[@class ="person-contact"]/p/a/span/text()').get()
        contact_address_street = response.xpath('//*[@class ="adr"]/text()').get()
        contact_address_plz = response.xpath('//*[@class ="locality"]/text()').getall()
        contact_state = response.xpath('//*[@class ="country-name"]/text()').get()

        yield{'Startup':startup_name,
              'Homepage': startup_hompage,
              'Description': startup_description,
              'Branche': branche,
              'Gründungsdatum': founded,
              'Anzahl Mitarbeiter':employees,
              'Kapital Bedarf':capital,
              'Datum des Förderbescheids':applied_for_invest,
              'Contact': contact_name,
              'Telefon':contact_phone,
              'E-Mail':contact_mail,
              'Adresse': contact_address_street + contact_address_plz + contact_state}
        
0
Simon Hofmann 25 Ноя 2022 в 21:16
Как запустить паука?
 – 
Alexander
26 Ноя 2022 в 02:50

2 ответа

Вам нужно запустить в приглашении: scrapy crawl -o имя файла (json или csv)

0
Matheus Araldi 25 Ноя 2022 в 21:56
Добро пожаловать в stackoverflow.com. Прочтите это.
 – 
SuperUser
26 Ноя 2022 в 10:55
  1. Вы не получаете вывод, потому что ваш allowed_domains неверен.
  2. В последней строке (Adresse) вы пытаетесь объединить типы list и str, поэтому получите ошибку.
  3. Ваша ссылка на страницу неверна, на первой странице вы получаете следующую страницу, а на второй странице вы получаете предыдущую страницу.
  4. Вы не выполняете проверку ошибок. На некоторых страницах вы получаете None для некоторых значений и пытаетесь получить их i-й символ, что приводит к ошибке.

Я исправил 1, 2 и 3. Но вам нужно будет исправить номер 4 самостоятельно.

import scrapy


class StartupsSpider(scrapy.Spider):
    # name of the spider
    name = 'startups'

    # list of allowed domains
    allowed_domains = ['bmwk.de']

    # starting url
    start_urls = ['https://bmwk.de/Navigation/DE/InvestDB/INVEST-DB_Liste/investdb.html']
    
    def parse(self, response):
        # parse initial start URL for the specific startup URL
        startups = response.xpath('//*[contains(@class,"card-link-overlay")]/@href').getall()

        for startup in startups:
            absolute_url = response.urljoin(startup)

            # parse the actual startup information
            yield scrapy.Request(absolute_url, callback=self.parse_startup)

        # link to next page
        next_page_url = response.xpath('(//*[@class ="pagination-link"])[last()]/@href').get()
        if next_page_url:
            # go through all pages on start URL
            absolute_next_page_url = response.urljoin(next_page_url)
            yield scrapy.Request(absolute_next_page_url)

    def parse_startup(self, response):
        # get information regarding startup
        startup_name = response.css('h1::text').get()
        startup_hompage = response.xpath('//*[@class="document-info-item"]/a/@href').get()
        # for example for some of the pages you'll get an error here:
        startup_description = response.css('div.document-info-item::text')[16].get()
        branche = response.css('div.document-info-item::text')[4].get()
        founded = response.xpath('//*[@class="date"]/text()')[0].getall()
        employees = response.css('div.document-info-item::text')[9].get()
        capital = response.css('div.document-info-item::text')[11].get()
        applied_for_invest = response.xpath('//*[@class="date"]/text()')[1].getall()

        contact_name = response.css('p.card-title-subtitle::text').get()
        contact_phone = response.css('p.tel > span::text').get()
        contact_mail = response.xpath('//*[@class ="person-contact"]/p/a/span/text()').get()
        Adresse = ' '.join(response.xpath('//*[@class ="address"]//text()').getall())

        yield {'Startup': startup_name,
               'Homepage': startup_hompage,
               'Description': startup_description,
               'Branche': branche,
               'Gründungsdatum': founded,
               'Anzahl Mitarbeiter': employees,
               'Kapital Bedarf': capital,
               'Datum des Förderbescheids': applied_for_invest,
               'Contact': contact_name,
               'Telefon': contact_phone,
               'E-Mail': contact_mail,
               'Adresse': Adresse}
0
SuperUser 26 Ноя 2022 в 10:53