Я прочитал этот вопрос и этот вопрос, и, возможно, больше вопросов, и хочу сделать именно то, что они там делают, но я просто получаю пустые результаты, когда пытаюсь.
Я хочу извлечь ссылку на профиль для всех подписчиков здесь https://www.facebook.com/zuck/followers
Очень грубый Xpath, указывающий на имя подписчика, которое является кликабельной ссылкой: //*[@id = "mount_0_0_MW"]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div/div/div[4]/div/div/div/div/div/div/div/div/div[3]/div/div[2]/div[1]/a
Тег a
, на который я указываю, обычно выглядит примерно так:
<a class = "x1i10hfl xjbqb8w x6umtig x1b1mbwd xaqea5y xav7gou x9f619 x1ypdohk xt0psk2 xe8uvvx xdj266r x11i5rnm xat24cr x1mh8g0r xexx8yu x4uap5 x18d9i69 xkhd6sd x16tdsg8 x1hl2dhg xggy1nq x1a2a7pz x1heor9g xt0b8zv"
href="https://www.facebook.com/profile.php?id=100072622654958" role = "link" tabindex = "0">
Чтобы извлечь значение href, я, согласно связанному вопросу, добавляю /@href
в конец xpath выше, но когда я оцениваю это выражение, используя $x в консоли браузера (в Safari), я получаю пустой результат:
Как мне переписать свой xpath, чтобы получить массив со значениями в атрибуте href при его оценке?
Попробуйте XPath следующим образом:
//a[starts-with(@href, "https://www.facebook.com/profile.php?")]/@href
В инструментах разработчика Chrome:
$x('//a[starts-with(@href, "https://www.facebook.com/profile.php?")]/@href')
Результат:
Array(24) [
href = "https://www.facebook.com/profile.php?id=100025227933647",
href = "https://www.facebook.com/profile.php?id=100025227933647",
href = "https://www.facebook.com/profile.php?id=100004202773657",
href = "https://www.facebook.com/profile.php?id=100004202773657",
href = "https://www.facebook.com/profile.php?id=100089136296666",
href = "https://www.facebook.com/profile.php?id=100089136296666",
href = "https://www.facebook.com/profile.php?id=100088772316924",
href = "https://www.facebook.com/profile.php?id=100088772316924",
href = "https://www.facebook.com/profile.php?id=100090228025189",
href = "https://www.facebook.com/profile.php?id=100090228025189",
… ]
... или, может быть, если вы хотите начать с ограничения поиска в определенной части страницы, как в приведенном выше примере XPath:
//*[@id = "mount_0_0_MW"]//a[starts-with(@href, "https://www.facebook.com/profile.php?")]/@href
Это поиск a
элементов, ссылки на которые ведут на страницы профиля Facebook.
Я видел много вопросов на этом сайте, когда у людей возникают проблемы с XPath, предложенным их браузером, и их выражение выглядит примерно так:
/div[2]/div[2]/div[1]/div[3]/div[1]/a
Выражения XPath, подобные этим, легко генерируются браузером, так как они просто восходят от выбранного элемента вверх по иерархии элементов, считая предшествующих братьев и сестер на каждом уровне. Но обычно они не очень надежны, потому что они зависят от HTML-страницы, имеющей фиксированную структуру, которая не меняется. Если бы страница добавила дополнительный элемент div
в какой-то ключевой части страницы, то XPath мог бы легко в конечном итоге указать куда-то не туда, куда он указывал раньше.
По моему мнению, людям часто лучше самим написать XPath, который выражает то, что они на самом деле ищут. В вашем случае вы на самом деле не ищете элементы a
, которые появляются на определенном уровне в иерархии div
; вы на самом деле ищете ссылки на профили. XPath, ориентированный на семантику вашего поиска, вероятно, будет более надежным и устойчивым перед лицом изменений.
Основываясь на вашем описании (и без доступа к Mac/Safari для тестирования), похоже, что оценка XPath для узла атрибута каким-то образом терпит неудачу, в качестве альтернативы я думаю, что вы можете полагаться на XPath только для выбора элементов @href
. , затем используйте методы массива JavaScript, такие как a
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) и обычные свойства DOM браузера, такие как map
; это означало бы, что вы используете, например.
$x('//*[@id = "mount_0_0_MW"]/div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div/div/div[4]/div/div/div/div/div/div/div/div/div[3]/div/div[2]/div[1]/a').map(link => link.href)
где вызов .href
возвращает массив узлов элементов $x(..)
, а последующий вызов a
отображает этот массив узлов элементов map
в массив строковых значений на основе свойства a
элементов href
.