1 (изменено: Malcev, 2020-12-02 14:02:45)

Тема: AHK: авторизация в фейсбуке

email := "blah-blah@gmail.com"
password := "pass"

HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
HTTP.Open("GET", "https://facebook.com", true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.SetRequestHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
HTTP.SetRequestHeader("sec-fetch-dest", "document")
HTTP.SetRequestHeader("sec-fetch-mode", "navigate")
HTTP.SetRequestHeader("sec-fetch-site", "same-origin")
HTTP.SetRequestHeader("sec-fetch-user", "?1")
HTTP.SetRequestHeader("upgrade-insecure-requests", "1")
HTTP.Send()
HTTP.WaitForResponse()
RegExMatch(HTTP.ResponseText, "s)""__spin_t"":(.+?),.+?<input type=""hidden"" name=""(.+?)"" value=""(.+?)"".+?name=""(.+?)"" value=""(.+?)"".+?_js_datr"",""(.+?)""", match)
datr := match6

HTTP.Open("POST", "https://www.facebook.com/login/?privacy_mutation_token=" URIEncode(b64Encode("{""type"":0,""creation_time"":" match1 ",""callsite_id"":381229079575946}")), true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.SetRequestHeader("content-type", "application/x-www-form-urlencoded")
HTTP.SetRequestHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
HTTP.SetRequestHeader("origin", "https://www.facebook.com")
HTTP.SetRequestHeader("referer", "https://www.facebook.com")
HTTP.SetRequestHeader("sec-fetch-dest", "document")
HTTP.SetRequestHeader("sec-fetch-mode", "navigate")
HTTP.SetRequestHeader("sec-fetch-site", "same-origin")
HTTP.SetRequestHeader("sec-fetch-user", "?1")
HTTP.SetRequestHeader("upgrade-insecure-requests", "1")
HTTP.SetRequestHeader("cookie", "datr=" datr)
HTTP.Send(match2 "=" match3 "&" match4 "=" match5 "&email=" URIEncode(email) "&login_source=comet_headerless_login&next=&encpass=" URIEncode(password))
HTTP.WaitForResponse()
msgbox % HTTP.ResponseText



URIEncode(str, encoding := "UTF-8")
{
   VarSetCapacity(var, StrPut(str, encoding))
   StrPut(str, &var, encoding)

   While code := NumGet(Var, A_Index - 1, "UChar")  {
      bool := (code > 0x7F || code < 0x30 || code = 0x3D)
      UrlStr .= bool ? "%" . Format("{:02X}", code) : Chr(code)
   }
   Return UrlStr
}

b64Encode(string)
{
    VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 
    if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1|0x40000000, "ptr", 0, "uint*", size))
        throw Exception("CryptBinaryToString failed", -1)
    VarSetCapacity(buf, size << 1, 0)
    if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x1|0x40000000, "ptr", &buf, "uint*", size))
        throw Exception("CryptBinaryToString failed", -1)
    return StrGet(&buf)
}
+ DD

2

Re: AHK: авторизация в фейсбуке

Вот бы еще для подгружаемой в профилях ленты код организовать, а то тоже не банально.

3

Re: AHK: авторизация в фейсбуке

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

4

Re: AHK: авторизация в фейсбуке

Уважаемый, почему получить контент в удобном виде, а не как это выдаёт фейсбук - нечестно?) К примеру, чтобы добраться до старых постов профиля, фейсбук предлагает честно попотеть). И как замечено, он не всё выдаёт — в зависимости от региона, профиля и тп. Имеется в виду просто работа ленты с подгрузкой постов.

5

Re: AHK: авторизация в фейсбуке

DD пишет:

Уважаемый, почему получить контент в удобном виде, а не как это выдаёт фейсбук - нечестно?

Получить доступ вашего приложения к группам, можно только с разрешения администратора группы.
Для вашей же задачи администратором являетесь вы, поэтому без труда можете дать себе нужный токен.

6

Re: AHK: авторизация в фейсбуке

Имелось в виду скачивание какого-то профиля со всеми постами. То есть, сразу по открытии профиля там лента со ссылками на посты профиля, которые хотелось бы получать. До недавнего времени я пользовался через скрипт мобильной версией сайта, в котором вместо подгрузок были переходы по истории, но теперь это убрали.

7

Re: AHK: авторизация в фейсбуке

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

8 (изменено: Xameleon, 2020-12-04 23:20:27)

Re: AHK: авторизация в фейсбуке

Приветствую, господа. Решил проверить работает ли старый подход к решению задачи. Первым делом, как и говорил DD, обратился именно к мобильный версии сайта, так как она меньше завязана на современные скрипты и грузит меньше HTML кода. Авторизация проходит без проблем. По концу сделал получение списка друзей, так как в моём аккаунте нет постов. Но думаю сам подход может пригодится тем, кто будет копать эту затею дальше. Какие плюсы вижу в таком решении:
1) Основной разбор данных страницы делается через HTMLDocument. Следовательно проще работать с деревом документа и с последующими страницами.
2) Благодаря тому же HTMLDocument получаем полный набор полей формы авторизации. Таким образом значения полей, призванные для защиты от автоматической, авторизации успешно обрабатываются.

Возможно тоже самое можно сделать через АПИ, но пока туда не забредал. Захотелось поэкспериментировать с текущими условиями.

P.S Код на JS, так как AHK мне так и не стал близок.


// Константы для WinHttpRequest
var WinHttpRequestOption_UserAgentString = 0,
	WinHttpRequestOption_URL = 1;

// Создание объекта для работы c веб ресурсами
var whr = WSH.CreateObject('WinHttp.WinHttpRequest.5.1');
// Установка User-Agent, чтобы сайт опознавал нас как мобильное устройство
//whr.Option(WinHttpRequestOption_UserAgentString) = 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+';
whr.Option(WinHttpRequestOption_UserAgentString) = 'Nokia7610/2.0 (5.0509.0) SymbianOS/7.0s Series60/2.1 Profile/MIDP-2.0 Configuration/CLDC-1.0'
// Загрузка страницы авторизации
WSH.Echo("Loading main page...");
whr.open('GET','https://m.facebook.com/login',false);
whr.send();
// Парсинг страницы (вторым параметром передаётся базовый URL страницы, чтобы все относительные ссылки внутри документа возвращали полный адрес)
var document = documentFromHTML(whr.responseText,whr.Option(WinHttpRequestOption_URL));
if(document.forms.length < 1){
	WSH.Echo('Authorization form not found !');
	WSH.Quit();
} 
// Получение полей формы
var form = document.forms[0];
// Заполнение логина и пароля в форме
form.elements['email'].value ='user@mail.com';
form.elements['pass'].value = 'password';
// Эмуляция отправки формы на сервер
WSH.Echo("Authorizing...");
whr.open('POST',form.action,false);
whr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// Отправка данных формы для авторизации на сайте. Сначала поля формы преобразуются к JSON объекту, а потом уже в строку параметров
whr.send(toQueryString(formDataToJSON(form)));
// Косвенная проверка успешности авторизации. При успешном исходе в URL присутсвует подстрока login/save-device
if(!/login\/save-device/i.test(whr.Option(WinHttpRequestOption_URL))){
	WSH.Echo("Login failed.");
	WSH.Quit();
}
// Получение страницы с данными по друзьям
WSH.Echo("Loading friend list...");
whr.open('GET','https://m.facebook.com/buddylist.php?ref_component=mbasic_home_header&ref_page=MChatBuddyListController',false);
whr.send();
// Парсим HTML содержимое
var document = documentFromHTML(whr.ResponseText);
// Выбираем все ссылки с классом "bm" внутри div элемента с классом "bx by bz"
var elements = document.querySelectorAll("div.bx.by.bz a.bm");
for(var i=0;i < elements.length;i++){
	WSH.Echo(elements[i].innerText);
}

// Обработка полей формы и создание объекта
function formDataToJSON(form){
	var object = {};
	for(var i=0;i < form.elements.length;i++){
		object[form.elements[i].name] = form.elements[i].value;
	}
	return object
}

// Функция преобразования HTML текста в объектную модель HTML документа
function documentFromHTML(text,baseURL){
	var document = new ActiveXObject('htmlfile');
	// Включение максимально доступной версии парсера IE
	document.write('<meta http-equiv="X-UA-Compatible" content="IE=Edge">' + text);
	document.close();
	// Добавление базового URL
	if(baseURL){
		var base = document.createElement('base');
		base.href = baseURL;
		document.all.tags('head')[0].appendChild(base);
	}
	return document
}
// Функция преобразования JS объектов и массивов в строку параметров для запроса a=1&b=2&c=3....
//https://stackoverflow.com/questions/1714786/query-string-encoding-of-a-javascript-object
//https://stackoverflow.com/questions/1714786/query-string-encoding-of-a-javascript-object#comment19642330_1714899
function toQueryString(obj, prefix) {
    var str = [];
	for (var p in obj) {
		if (obj.hasOwnProperty(p)) {
			var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
			str.push(typeof v == "object" ? toQueryString(v, k) : encodeURIComponent(k) + "=" + encodeURIComponent(v));
		}
	}
    return str.join("&").replace(/%20/g,'+');
}
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

9

Re: AHK: авторизация в фейсбуке

Xameleon пишет:

Первым делом, как и говорил DD, обратился именно к мобильный версии сайта, так как она меньше завязана на современные скрипты и грузит меньше HTML кода

Это не всегда так.
Например при переходе на объявления в группе, мобильная версия загружается в 6 раз дольше простой (3000ms против 500ms), так как простая загружает только 3 последних объявления, а мобильная 20.

10

Re: AHK: авторизация в фейсбуке

Malcev, понял. Спасибо за информацию. Не сравнивал в этом ключе. Встречно хотел уточнить - но тогда же ведь получается есть смысл грузить как раз мобильную, чтобы получить больше информации за 1 раз ? Ведь если есть задача получить объявления, то всё равно придётся грузить множество ? И кстати, у вас на какой версии так себя ведёт сайт - на версии под Android или под WAP или одинаково ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

11

Re: AHK: авторизация в фейсбуке

Я сейчас потестировал и информация оказалось ложной.
Там получается так.
В мобильной версии мы действительно получаем в группе 20 сообщений сразу, но так как она мобильная, то грузится за такое же время как обычная с 3 сообщениями.
Но проблема в мобильной в том, что нельзя сообщения рассортировать в хронологическом порядке, а только по последней активности (во всяком случае я не нашел такого параметра).
А мне надо было написать скрипт, который реагирует на новое сообщение, поэтому, полагаю, я обычную версию загружал в мобильную и соответственно получал увеличенное время ожидания.

12 (изменено: svoboden, 2021-11-01 09:25:28)

Re: AHK: авторизация в фейсбуке

Я залогинился и меня заблокировал фейсбук. https://i.imgur.com/5S5NAXK.jpg. Хорошо, что аккаунт новый был, не жалко. Хотел восстановить аккаунт, не восстановили.

13

Re: AHK: авторизация в фейсбуке

Моим кодом?

14

Re: AHK: авторизация в фейсбуке

Да, по вашему примеру. Но ничего, я новый зарегистрировал.

15

Re: AHK: авторизация в фейсбуке

Странно, меня пока не блокирует.