Scrap не соскабливать, если один элемент отсутствует - PullRequest
2 голосов
/ 06 июля 2019

Я построил свой первый паук-скребок за несколько часов за последние два дня, но я застрял прямо сейчас - главная цель, которую я хотел достичь, - извлечь все данные, чтобы затем отфильтровать их в CSV. Теперь действительно важные для меня данные (компании без! Веб-страниц) отбрасываются, потому что scrapy не может найти предоставленный мною xpath, если у элемента есть домашняя страница. Я попробовал заявление if здесь, но это не работает.

Пример сайта: https://www.achern.de/de/Wirtschaft/Unternehmen-A-Z/Unternehmen?view=publish&item=company&id=1345

Я использую селектор xPath: response.xpath("//div[@class='cCore_contactInformationBlockWithIcon cCore_wwwIcon']/a/@href").extract()

Пример не веб-сайта: https://www.achern.de/de/Wirtschaft/Unternehmen-A-Z/Unternehmen?view=publish&item=company&id=1512

Код паука:

# -*- coding: utf-8 -*-
import scrapy

class AchernSpider(scrapy.Spider):
name = 'achern'
allowed_domains = ['www.achern.de']
start_urls = ['https://www.achern.de/de/Wirtschaft/Unternehmen-A-Z/']



def parse(self, response):
    for href in response.xpath("//ul[@class='cCore_list cCore_customList']/li[*][*]/a/@href"):
        url = response.urljoin(href.extract())
        yield scrapy.Request(url, callback= self.scrape)

def scrape(self, response):
    #Extracting the content using css selectors
    print("Processing:"+response.url)
    firma = response.css('div>#cMpu_publish_company>h2.cCore_headline::text').extract()
    anschrift = response.xpath("//div[contains(@class,'cCore_addressBlock_address')]/text()").extract()
    tel = response.xpath("//div[@class='cCore_contactInformationBlockWithIcon cCore_phoneIcon']/text()").extract()
    mail = response.xpath(".//div[@class='cCore_contactInformationBlock']//*[contains(text(), '@')]/text()").extract()
    web1 = response.xpath("//div[@class='cCore_contactInformationBlockWithIcon cCore_wwwIcon']/a/@href").extract()
    if "http:" not in web1:
        web = "na"
    else:
        web = web1

    row_data=zip(firma,anschrift,tel,mail,web1) #web1 must be changed to web but then it only give out "n" for every link
    #Give the extracted content row wise
    for item in row_data:
        #create a dictionary to store the scraped info
        scraped_info = {
            'Firma' : item[0],
            'Anschrift' : item[1] +' 77855 Achern',
            'Telefon' : item[2],
            'Mail' : item[3],
            'Web' : item[4],
        }

        #yield or give the scraped info to scrapy
        yield scraped_info

Таким образом, в общем случае он должен экспортировать УРОЖАЕМЫЕ предметы, даже если нет «паутины» ..

Надеюсь, что кто-то может помочь, привет S

1 Ответ

1 голос
/ 06 июля 2019

Использование

response.css(".cCore_wwwIcon > a::attr(href)").get()

дает вам None или адрес веб-сайта, затем вы можете использовать or для предоставления значения по умолчанию:

website = response.css(".cCore_wwwIcon > a::attr(href)").get() or 'na'

Кроме того, я рефакторинг вашегоСкребок для использования CSS селекторов.Обратите внимание, что я использовал .get() вместо .extract(), чтобы получить один элемент, а не список, который немного очищает код.

import scrapy
from scrapy.crawler import CrawlerProcess

class AchernSpider(scrapy.Spider):
    name = 'achern'
    allowed_domains = ['www.achern.de']
    start_urls = ['https://www.achern.de/de/Wirtschaft/Unternehmen-A-Z/']

    def parse(self, response):
        for url in response.css("[class*=cCore_listRow] > a::attr(href)").extract():
            yield scrapy.Request(url, callback=self.scrape)

    def scrape(self, response):
        # Extracting the content using css selectors
        firma = response.css('.cCore_headline::text').get()
        anschrift = response.css('.cCore_addressBlock_address::text').get()
        tel = response.css(".cCore_phoneIcon::text").get()
        mail = response.css("[href^=mailto]::attr(href)").get().replace('mailto:', '')
        website = response.css(".cCore_wwwIcon > a::attr(href)").get() or 'na'

        scraped_info = {
            'Firma': firma,
            'Anschrift': anschrift + ' 77855 Achern',
            'Telefon': tel,
            'Mail': mail,
            'Web': website,
        }
        yield scraped_info


if __name__ == "__main__":
    p = CrawlerProcess()
    p.crawl(AchernSpider)
    p.start()

output:

with website:
{'Firma': 'Wölfinger Fahrschule GmbH', 'Anschrift': 'Güterhallenstraße 8 77855 Achern', 'Telefon': '07841 6738132', 'Mail': 'info@woelfinger-fahrschule.de', 'Web': 'http://www.woelfinger-fahrschule.de'}

without website:
{'Firma': 'Zappenduster-RC Steffen Liepe', 'Anschrift': 'Am Kirchweg 16 77855 Achern', 'Telefon': '07841 6844700', 'Mail': 'Zappenduster-Rc@hotmail.de', 'Web': 'na'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...