Бьёмся с xPath и Facebook

GoogleMo

Client
Регистрация
13.04.2014
Сообщения
225
Благодарностей
8
Баллы
18
Решил я наконец запилить простенький скрипт для работы с ФБ, для автоматизации огромного кол-ва обезьяньей работы и завис...

Задача у меня такая:
1) на странице друзей - https://www.facebook.com/friends/ анализировать предложенные варианты друзей и добавлять только те, что удовлетворяют моим требованиям:
а) имя кириллицей
б) общих друзей меньше n
в) человек не находится в друзьях у других аккаунтов
г) жмём добавить в друзья

Кажется всё довольно просто, парсим список, анализируем 3 элемента каждого (урл, имя, кол-во общих друзей) и жмём добавить.

Вот только когда я спарсил список в xPath я увидел такой треш, по айди классов у меня ничерта не вышло, потому что они рандомно генерируются постоянно, а значит работать придётся по абсолютным позициям div\span\a и т.д.

Но даже так, при первом заходе первая позиция имеет такой xPath (он у меня, к слову, в таком виде не работает, что-то я где-то упускаю)
/html/body/div[1]/div[1]/div[1]/div[1]/div[922]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[11]/div[1]/div[2]/div[1]/div[24]/div[1]/a[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]/span

А при втором заходе (на том же аккаунте), первая позиция уже такая
/html/body/div[1]/div[1]/div[1]/div[1]/div[927]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[11]/div[1]/div[2]/div[1]/div[24]/div[1]/a[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]/span

И вообщем, я встрял. Ищу совета у опытных юзеров xPath. Ну или знатоков работы с ФБ.
 

backoff

Client
Регистрация
20.04.2015
Сообщения
5 942
Благодарностей
6 413
Баллы
113
такие пути однозначно работать не будут, их надо писать руками
то что надо по ТЗ думаю в одном пути не сделать, ну или я не знаю как

Кажется всё довольно просто, парсим список, анализируем 3 элемента каждого (урл, имя, кол-во общих друзей) и жмём добавить.
логика правильная, я бы так и делал, только пути сделаны автоматом, тут так не прокатит


как пример на скорую руку:
C#:
//div[@data-visualcompletion="ignore-dynamic"]
 

alex8020

Client
Регистрация
16.08.2016
Сообщения
37
Благодарностей
39
Баллы
18
Может получится от этого пути оттолкнуться
C#:
//a[contains(@href, 'profile.php?id=')]
 
  • Спасибо
Реакции: GoogleMo

GoogleMo

Client
Регистрация
13.04.2014
Сообщения
225
Благодарностей
8
Баллы
18
такие пути однозначно работать не будут, их надо писать руками
то что надо по ТЗ думаю в одном пути не сделать, ну или я не знаю как


логика правильная, я бы так и делал, только пути сделаны автоматом, тут так не прокатит


как пример на скорую руку:
C#:
//div[@data-visualcompletion="ignore-dynamic"]
К сожалению, это класс, который идентичен у всех пользователей, по нему нельзя "прицепиться" и определить конкретного.


Может получится от этого пути оттолкнуться
C#:
//a[contains(@href, 'profile.php?id=')]
Вот это интересное решение, и пока у меня получается спарсить список УРЛ и по нему определить ники, кол-во друзей и кнопку. Пока что всё работает, схема у меня вышла такая, вдруг кому пригодится:

для имени:
//a[contains(@href, 'https://www.facebook.com/profile.php?id=')]//span/span/span

для кол-ва общих друзей
//a[contains(@href, 'https://www.facebook.com/profile.php?id=')]//div[@aria-labelledby]/span

для кнопки добавить:
//a[contains(@href, 'https://www.facebook.com/profile.php?id=')]//div[@aria-label="Добавить"]

Но боюсь, тут надо следить за изменениями ФБ, ибо, структура уж очень сильно привязана к легко изменяемым деталям.
 

backoff

Client
Регистрация
20.04.2015
Сообщения
5 942
Благодарностей
6 413
Баллы
113
по нему нельзя "прицепиться" и определить конкретного.
можно, если конкретизировать номером
C#:
(//div[@data-visualcompletion="ignore-dynamic"])[3]
брать блок со всей инфой нужной и распарсить его на нужные куски
 

Ysocnet

Client
Регистрация
24.09.2019
Сообщения
95
Благодарностей
56
Баллы
18
Решил я наконец запилить простенький скрипт для работы с ФБ, для автоматизации огромного кол-ва обезьяньей работы и завис...

Задача у меня такая:
1) на странице друзей - https://www.facebook.com/friends/ анализировать предложенные варианты друзей и добавлять только те, что удовлетворяют моим требованиям:
а) имя кириллицей
б) общих друзей меньше n
в) человек не находится в друзьях у других аккаунтов
г) жмём добавить в друзья

Кажется всё довольно просто, парсим список, анализируем 3 элемента каждого (урл, имя, кол-во общих друзей) и жмём добавить.

Вот только когда я спарсил список в xPath я увидел такой треш, по айди классов у меня ничерта не вышло, потому что они рандомно генерируются постоянно, а значит работать придётся по абсолютным позициям div\span\a и т.д.

Но даже так, при первом заходе первая позиция имеет такой xPath (он у меня, к слову, в таком виде не работает, что-то я где-то упускаю)
/html/body/div[1]/div[1]/div[1]/div[1]/div[922]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[11]/div[1]/div[2]/div[1]/div[24]/div[1]/a[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]/span

А при втором заходе (на том же аккаунте), первая позиция уже такая
/html/body/div[1]/div[1]/div[1]/div[1]/div[927]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[11]/div[1]/div[2]/div[1]/div[24]/div[1]/a[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]/span

И вообщем, я встрял. Ищу совета у опытных юзеров xPath. Ну или знатоков работы с ФБ.
Если тебе не принципиально, то можешь сделать через мобильные UA. Там вроде до сих пор явные атрибуты, по которым можно составить адекватный путь
 

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 445
Благодарностей
3 351
Баллы
113
/html/body/div[1]/div[1]/div[1]/div[1]/div[922]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[11]/div[1]/div[2]/div[1]/div[24]/div[1]/a[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]/span

А при втором заходе (на том же аккаунте), первая позиция уже такая
/html/body/div[1]/div[1]/div[1]/div[1]/div[927]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[11]/div[1]/div[2]/div[1]/div[24]/div[1]/a[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]/span
Подобное составление не имеет смысла.

Суть использования XPath в поиске фиксированных элементов в DOM и уже постройка от них пути,
при этом, можно подниматься по родительским элементам, но надо помнить, что бы путь был короток.

Изучите:

Хорошо себя показывает XPath в C#, когда можно разделить основные пути по задачам (и в случае ошибки писать внятное сообщение), а так же переиспользовать уже найденные элементы.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 744
Благодарностей
1 928
Баллы
113
  • Спасибо
Реакции: Astraport

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 952
Благодарностей
4 376
Баллы
113
Я бы цеплялся к div c aria-label="Подтвердить" (тут важно чтобы акки были с включенным русским языком, если нет, то включаем в настройках). Поднимался по дереву элементов до нужных div, собирал их данные со всеми проверками на пустоту и валидность, анализировал, и, если всё ОК, жал на тот div что уже определён вначале.
 

GoogleMo

Client
Регистрация
13.04.2014
Сообщения
225
Благодарностей
8
Баллы
18
Неплохое расширение, может пригодится, но тут оно неоч хорошие варианты подсказывает, уж больно мудрёная у ФБ структура.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 744
Благодарностей
1 928
Баллы
113
уж больно мудрёная у ФБ структура.
Поэтому нужно только ручное составление xpath и проверка на разных страницах. Плагин помогает при проверке составленного пути, и можно посмотреть код найденных элементов, что очень удобно.
 

dizney

Client
Регистрация
25.01.2014
Сообщения
51
Благодарностей
52
Баллы
18
Вот накидал для получения имени. Таким же способом брать все остальные значения.

C#:
var tab = instance.ActiveTab;
var fio = tab.FindElementByXPath(@"//span[text()='Подтвердить']/ancestor::div[9]/following::span[4]", 0).GetAttribute("innertext");
project.SendInfoToLog(fio);
 

GoogleMo

Client
Регистрация
13.04.2014
Сообщения
225
Благодарностей
8
Баллы
18
Вот накидал для получения имени. Таким же способом брать все остальные значения.

C#:
var tab = instance.ActiveTab;
var fio = tab.FindElementByXPath(@"//span[text()='Подтвердить']/ancestor::div[9]/following::span[4]", 0).GetAttribute("innertext");
project.SendInfoToLog(fio);
Ну это тоже вариант, хотя мне больше тот, что я сверху расписал понравился.
 
Последнее редактирование:

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 705
Баллы
113

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)