diff --git a/core/command.py b/core/command.py index 1636b7e..c1fb36e 100644 --- a/core/command.py +++ b/core/command.py @@ -145,3 +145,15 @@ class Executor(): 'next_url': 'https://www.facebook.com' + next_url if next_url else None } return data + + def fetchUserInfo(self, fbid_list): + if not isinstance(fbid_list, (tuple, list)): + raise BaseException("fbid_list 参数要求是文本型列表") + users = self.client.fetchUserInfo(*fbid_list) + keys = ['type', 'gender', 'is_friend', 'name', 'photo', 'uid', 'url'] + objects = [] + for _, u in users.items(): + info = common.todict(u, include=keys) + info['type'] = info.get('type').name + objects.append(info) + return objects diff --git a/lib/facebook.py b/lib/facebook.py index 43748e5..6562ca1 100644 --- a/lib/facebook.py +++ b/lib/facebook.py @@ -5,7 +5,6 @@ # @File : facebook.py # @Software: PyCharm import base64 -import itertools import json import os import random @@ -335,7 +334,9 @@ class FacebookClient(Client): data = {'current_city_text': city_name, 'current_city': city_id, 'privacy[8787650733]': PostParam.EVERYONE.value} res = self._post('/profile/async/edit/infotab/save/current_city/', data) - return res + if city_id in res['domops'][0][3]['__html']: + return {"success": True} + return {"success": False} def setHometown(self, city_id, city_name): ''' @@ -345,7 +346,9 @@ class FacebookClient(Client): 'nctr[_mod]': 'pagelet_hometown', 'privacy[8787655733]': PostParam.EVERYONE.value} res = self._post("/profile/async/edit/infotab/save/hometown/", data) - return res + if city_id in res['domops'][0][3]['__html']: + return {"success": True} + return {"success": False} def setGender(self, gender: str): ''' @@ -357,7 +360,7 @@ class FacebookClient(Client): res = self._post('/profile/edit/infotab/save/gender/', data) html = parse_html.get_domops_3(res) - if 'Gender' in html: + if 'gender' in html: return {"success": True} else: raise BaseException("未知错误:", html) @@ -734,10 +737,15 @@ class FacebookClient(Client): def get_user_agent(self): return self._state._session.headers.get('User-Agent', random.choice(_util.USER_AGENTS)) - def searchForUserByFilter(self, ext_data=None): + def searchForUserByFilter(self, name, city_id, ext_data=None): if not ext_data: + from urllib import parse + tob64 = lambda x: str(base64.b64encode(x.encode('utf-8')), 'utf-8') + filter = json.dumps({'city': json.dumps({"name": "users_location", "args": str(city_id)})}) + b64 = tob64(filter) + r = self._state._session.get( - 'https://www.facebook.com/search/people/?q=%E5%B1%B1%E4%B8%8B&epa=FILTERS&filters=eyJjaXR5Ijoie1wibmFtZVwiOlwidXNlcnNfbG9jYXRpb25cIixcImFyZ3NcIjpcIjEwNjUxNDAwNjA1MzI1MFwifSJ9') + f'https://www.facebook.com/search/people/?q={parse.quote(name)}&epa=FILTERS&filters={b64}') fbid = parse_html.get_all_raw_id(r.text) global_data = re.findall(r'globalData:(\{.*?display_params.*?\}),prefetchPixels', r.text)[0] @@ -758,10 +766,60 @@ class FacebookClient(Client): pass fbid = parse_html.get_all_raw_id(res['payload']) - if fbid and 'page_number' not in ext_data: - ext_data = None - # 无更多了 return { 'fbid_list': fbid, 'ext_data': ext_data, } + + def changePwd(self, old, new): + data = { + 'recommended': False, + 'fb_dtsg_ag': self._state.fb_dtsg_ag, + } + res = self._state._get('/settings/security/password/', data, 0) + data = parse_html.get_hidden_input(res) + assert 'password_change_session_identifier' in data, '参数不足:session_identifier未获取到' + data.update({ + "password_strength": 2, + 'password_old': old, + 'password_new': new, + 'password_confirm': new, + }) + res = self._post('/ajax/settings/security/password.php', data) + title = res['jsmods']['require'][0][0] + if title == 'SecuritySettingsPasswordErrorHandler': + html = res['jsmods']['require'][0][3][0]['__html'] + error = parse_html.get_div_text(html) + return {'success': False, 'error': error} + elif title == 'JSPasswordChangeReason': + return {'success': True, 'error': None} + else: + raise BaseException('未知错误:' + json.dumps(res['jsmods']['require'])) + + def setFriendListPrivate(self, value): + value = PostParam.__dict__.get(value).value + data = {'privacy_fbid': '8787365733', 'post_param': value, 'render_location_enum': 'settings', + 'is_saved_on_select': 'true', 'should_return_tooltip': 'false', + 'prefix_tooltip_with_app_privacy': 'false', 'ent_id': '0', 'user_id': self._uid} + self._post('https://www.facebook.com/privacy/selector/update?' + self._to_url_params(data), {}) + data = { + 'post_param': value, + 'value': value, + 'saved_custom_opt_in': True, + } + res = self._post('/ajax/settings/granular_privacy/friendlist.php', data) + if 'fbSettingsListItem' in res['domops'][0][1]: + return {"success": True} + return {"success": False} + + def setCanFriendReq(self, value): + value = PostParam.__dict__.get(value).value + data = {'privacy_fbid': '8787540733', 'post_param': value, 'render_location_enum': 'settings', + 'is_saved_on_select': True, 'should_return_tooltip': 'false', + 'prefix_tooltip_with_app_privacy': False, 'ent_id': '0', 'user_id': self.uid} + self._post('/privacy/selector/update/?' + self._to_url_params(data), {}) + data = {'post_param': value, 'saved_custom_opt_in': 'true', 'value': value} + res = self._post('/ajax/settings/granular_privacy/can_friend_req.php', data) + if 'fbSettingsListItem' in res['domops'][0][1]: + return {"success": True} + return {"success": False} diff --git a/utils/parse_html.py b/utils/parse_html.py index f7bb390..a609771 100644 --- a/utils/parse_html.py +++ b/utils/parse_html.py @@ -159,6 +159,22 @@ def get_all_raw_id(text): fbids = list(set(fbids)) else: r = re.compile(r'\\"raw_id\\":(\d+),') - key=r.findall(text) + key = r.findall(text) fbids.extend(key) return fbids + + +def get_hidden_input(res): + text = get_domops_3(res) + b = bs4.BeautifulSoup(text, 'html.parser') + ins = [x.attrs for x in b.find_all('input', type='hidden')] + + args = {} + for x in ins: + if 'name' in x and 'value' in x: + args.update({x['name']: x['value']}) + return args + +def get_div_text(html): + b = bs4.BeautifulSoup(html, 'html.parser') + return b.text