#python #python-3.x #scrapy
#python #python-3.x #scrapy
Вопрос:
Я хочу очистить все ссылки страниц с алфавитными названиями этого сайта:
То есть ссылки, подобные:
['/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. Спасибо! Черт, вы могли бы использовать регулярные выражения в этих фильтрах ?!