Как скрести вещи только тогда, когда автор не равен Альберту Эйнштейну - PullRequest
1 голос
/ 21 апреля 2020

Я хотел бы узнать, как извлечь цитаты и авторов из первой страницы http://quotes.toscrape.com/ ТОЛЬКО если имя автора не Альберт Эйнштейн.

<div class="quote">
    <span class="text">
        "some quote"
    </span
    <span>
        "by "
        <small class="author">Albert Einstein</small>
    </span>
    <span class="text">
        "some quote"
    </span
    <span>
        "by "
        <small class="author">J.K. Rowling</small>
    </span>

Я провел некоторый поиск, и самые близкие вещи, которые я могу найти, - это сообщения, но они относятся только к тому, чтобы не пересматривать, если атрибут не равен чему-то, и нет, если значение не равно что-то.

1 XPath для элементов с атрибутом, который не равен или не существует
2 Тест Xpath для атрибута предка не равен строка
3 Как использовать «not» в xpath?
4 Использование not () в XPath

В настоящее время у меня есть ...

class AllSpider(scrapy.Spider):
    name = 'working'
    start_urls = [
        'http://quotes.toscrape.com/',
    ]

def parse(self, response):
    divs = response.xpath("//div[@class='quote']")
    for div in divs:
        l = ItemLoader(item=AllItems(), selector=div)
        l.add_xpath('title', ".//span[@class='text']/text()")
        l.add_xpath('name', ".//small[@class='author']/text()")
        yield l.load_item()

class AllItems(scrapy.Item):
    link = scrapy.Field()
    title = scrapy.Field()
    name = scrapy.Field()
    domain = scrapy.Field()

и попробовал следующее, но, похоже, ничего не делает, и я получаю те же результаты, что и без добавления кода. Любая помощь будет оценена !!! Единственный другой способ, которым я мог бы думать об этом, - это пост-сканирование, когда я могу использовать pandas для фильтрации выходного файла .csv, но если есть способ сделать это с помощью scrapy, я бы с удовольствием изучил его!

def parse(self, response):
    divs = response.xpath("//div[@class='quote']")
    for div in divs:
        l = ItemLoader(item=AllItems(), selector=div)

        if l.add_xpath('name', ".//small[@class='author']/text()") != 'Albert Einstein':

            l.add_xpath('title', ".//span[@class='text']/text()")
            l.add_xpath('name', ".//small[@class='author']/text()")
            yield l.load_item()

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

Так что, поиграв с этим, я обнаружил, что лучшим способом сделать это было бы одно из этих решений. Первое, если у вас есть одно значение для фильтрации, а второе, если у вас есть список значений, которые вы хотите отфильтровать. Спасибо всем, кто помог мне !!!

def parse(self, response):
    divs = response.xpath("//div[@class='quote']")
    for div in divs:
        l = ItemLoader(item=AllItems(), selector=div)
        name = div.xpath(".//small[@class='author']/text()").get()
        if name != 'Albert Einstein':
            l.add_xpath('title', ".//span[@class='text']/text()")
            l.add_value('name', name)
            yield l.load_item()

или

def parse(self, response):
    authors_to_filter = ['Albert Einstein', 'Other Name']
    divs = response.xpath("//div[@class='quote']")
    for div in divs:
        l = ItemLoader(item=AllItems(), selector=div)
        name = div.xpath(".//small[@class='author']/text()").get()
        if name not in authors_to_filter:
            l.add_value('name', name)
            yield l.load_item()
0 голосов
/ 24 апреля 2020

Попробуйте скопировать и вставить это:

l.add_xpath ('name', ".// small [@ class = 'author'] [not (содержит (., 'Альберт Эйнштейн')) ] / текст () ")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...