#xpath #scrapy
#xpath #scrapy
Вопрос:
Я использую scrapy и пытаюсь найти интервал, содержащий определенный текст. У меня есть:
response.selector.xpath('//*[@class="ParamText"]/span/node()')
который возвращает:
<Selector xpath='//*[@class="ParamText"]/span/text()' data=u' MILES STODOLINK'>,
<Selector xpath='//*[@class="ParamText"]/span/text()' data=u'C'>,
<Selector xpath='//*[@class="ParamText"]/span/text()' data=u' MILES STODOLINK'>]
Однако, когда я запускаю:
>>> response.selector.xpath('//*[@class="ParamText"]/span[contains(text(),"STODOLINK")]')
Out[11]: []
Почему функция contains не работает?
Ответ №1:
contains()
невозможно оценить несколько узлов одновременно :
/span[contains(text(),"STODOLINK")]
Итак, в случае, если внутри есть несколько текстовых узлов span
, и "STODOLINK"
не находится в первом дочернем текстовом узле span
, то contains()
в приведенном выше выражении это не сработает. Вы должны попытаться применить contains()
проверку к отдельным текстовым узлам следующим образом :
//*[@class="ParamText"]/span[text()[contains(.,"STODOLINK")]]
Или, если "STODOLINK"
не обязательно находится непосредственно внутри span
(может быть вложен в другой элемент в span
), тогда вы можете просто использовать .
вместо text()
:
//*[@class="ParamText"]/span[contains(.,"STODOLINK")]
Комментарии:
1. Спасибо, могу я спросить, что здесь означает «.». Я предполагаю, что «любой символ», как в регулярном выражении?
2. Это ссылка на сам элемент. Кроме того, ‘..’ — это ссылка на родительский элемент; Они работают как в системах * nix (Linux, Mac и т. Д.) Пути к файлам, Где ‘.’ — текущий каталог, а ‘..’ — родительский каталог.
Ответ №2:
В моем терминале (предполагая, что мой пример идентичен вашему файлу) ваш код работает:
Ввод
import scrapy
example='<div class="ParamText"><span>STODOLINK</span></div>'
scrapy.Selector(text=example).xpath('//*[@class="ParamText"]/span[contains(text(),"STODOLINK")]').extract()
Вывод:
['<span>STODOLINK</span>']
Можете ли вы уточнить, что может быть по-другому?
Ответ №3:
Я использую Scrapy с BeautifulSoup4.0. IMO, Soup легко читать и понимать. Это вариант, если вам не нужно использовать HtmlXPathSelector . Ниже приведен пример поиска всех ссылок. Вы можете заменить это на ‘span’. Надеюсь, это поможет!
import scrapy
from bs4 import BeautifulSoup
import Item
def parse(self, response):
soup = BeautifulSoup(response.body,'html.parser')
print 'Current url: %s' % response.url
item = Item()
for link in soup.find_all('a'):
if link.get('href') is not None:
url = response.urljoin(link.get('href'))
item['url'] = url
yield scrapy.Request(url,callback=self.parse)
yield item