Очищать ссылки в соответствии с их длиной

#python #python-3.x #scrapy

#python #python-3.x #scrapy

Вопрос:

Я хочу очистить все ссылки страниц с алфавитными названиями этого сайта:

introducir la descripción de la imagen aquí

То есть ссылки, подобные:

 ['/pinpai/2-a.html','/pinpai/3-b.html'...]
  

Для того, чтобы очистить еще несколько вещей в них.

Следуя этому продвинутому руководству по созданию веб-страниц, я мотивировал себя изучить фильтрацию xpath. Поскольку они кажутся длиной менее 17 символов, и поскольку я нашел некоторые ресурсы для фильтрации длины в документе, я попытался отфильтровать ссылки по их длине в следующем пауке scrapy scraper:

 import scrapy

class NosetimeScraper(scrapy.Spider):
    name = "nosetime"
    start_urls = ['https://www.nosetime.com/pinpai/']

    def parse(self, response):
        # proceed to other pages of the listings
        for page_url in response.xpath('//a[contains(@href, "pinpai"), string-length(@href)<17]/@href').extract():
            print("page_url: ", page_url)
            page_url = response.urljoin(page_url)
            yield scrapy.Request(url=page_url, callback=self.parse)
  

Но получил:

   File "srclxmletree.pyx", line 1582, in lxml.etree._Element.xpath
  File "srclxmlxpath.pxi", line 305, in lxml.etree.XPathElementEvaluator.__call__
  File "srclxmlxpath.pxi", line 225, in lxml.etree._XPathEvaluatorBase._handle_result
lxml.etree.XPathEvalError: Invalid predicate

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyutilsdefer.py", line 120, in iter_errback
    yield next(it)
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyutilspython.py", line 353, in __next__
    return next(self.data)
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyutilspython.py", line 353, in __next__
    return next(self.data)
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
    for r in iterable:
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyspidermiddlewaresoffsite.py", line 29, in process_spider_output
    for x in result:
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
    for r in iterable:
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyspidermiddlewaresreferer.py", line 340, in <genexpr>
    return (_set_referer(r) for r in result or ())
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
    for r in iterable:
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyspidermiddlewaresurllength.py", line 37, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
    for r in iterable:
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyspidermiddlewaresdepth.py", line 58, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
    for r in iterable:
  File "C:UsersantoiDocumentsProgrammingLearningDataSciencenosetime_scrapernosetime_scraperspidersnosetime_spider.py", line 10, in parse
    for page_url in response.xpath('//a[contains(@href, "pinpai"), string-length(@href)<17]/@href').extract():
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesscrapyhttpresponsetext.py", line 139, in xpath
    return self.selector.xpath(query, **kwargs)
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesparselselector.py", line 260, in xpath
    six.reraise(ValueError, ValueError(msg), sys.exc_info()[2])
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagessix.py", line 702, in reraise
    raise value.with_traceback(tb)
  File "c:usersantoidocumentsprogramminglearningdatasciencescr_envlibsite-packagesparselselector.py", line 256, in xpath
    **kwargs)
  File "srclxmletree.pyx", line 1582, in lxml.etree._Element.xpath
  File "srclxmlxpath.pxi", line 305, in lxml.etree.XPathElementEvaluator.__call__
  File "srclxmlxpath.pxi", line 225, in lxml.etree._XPathEvaluatorBase._handle_result
ValueError: XPath error: Invalid predicate in //a[contains(@href, "pinpai"), string-length(@href)<17]/@href
  

Итак, как я могу фильтровать ссылки, которые я очищаю, в соответствии с их длиной? Я также подумал об их структуре {одна или две цифры} — {буква}, но не нашел ресурсов, которые помогли бы мне создать это в документе.

Комментарии:

1. замените в предикате на и «//a[содержит (@href, «pinpai») и длину строки (@href)<17]/@href»

Ответ №1:

Я считаю, что правильный синтаксис XPath

 '//a[contains(@href, "pinpai") and string-length(@href)<17]/@href'
  

Эта строка сработала для меня:

 response.xpath('//a[contains(@href, "pinpai") and string-length(@href)<17]/@href').extract()
  

FWIW вы также можете фильтровать ссылки с помощью регулярных выражений, но я думаю, что приведенный выше XPath должен работать так, как ожидалось.

Комментарии:

1. Спасибо! Черт, вы могли бы использовать регулярные выражения в этих фильтрах ?!