· 10 years ago · Apr 06, 2016, 04:45 AM
1from requests.adapters import HTTPAdapter
2from requests.packages.urllib3.poolmanager import PoolManager
3from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
4from bs4 import BeautifulSoup
5import logging
6import logging.handlers
7import traceback
8import urllib
9import requests
10import hashlib
11import random
12import time
13import json
14import csv
15import lxml.html
16import codecs
17import ssl
18
19# class MyAdapter(HTTPAdapter):
20# def init_poolmanager(self, connections, maxsize, block=False):
21# self.poolmanager = PoolManager(num_pools=connections,
22# maxsize=maxsize,
23# block=block,
24# ssl_version=ssl.PROTOCOL_TLSv1)
25
26class Musicallyfame():
27 def __init__(self):
28 self.phone_profiles = ["lava", "samsung", "oneplusone", "htc", "nexus"]
29 self.common_header = {
30 "os": "android 4.1.2",
31 "User-Agent": "Musical.ly/2016020601 (Android; LAVA LAVA 4.1.2;rv:16)",
32 "build": "2016020601",
33 "mobile": "LAVA Iris 501",
34 "version": "4.7.5",
35 "X-Requested-With": "XMLHttpRequest",
36 "language": "en_US",
37 "Connection": "close",
38 "network": "WiFi",
39 "Host": "www.musical.ly",
40 "Accept-Encoding": "gzip",
41 "MIME-Version":"1.0"
42 }
43 self.signing_server = "http://45.55.203.163:8888/sign"
44 self.signature_data = {"app":
45 {"-r":"Gvt1",
46 "os":"android 4.1.2",
47 "version":"4.7.5"},
48 "ostype":"and",
49 "imei":"51a4454f",
50 "mac":"4C:3C:16:82:EE:F3",
51 "model":"SM-G730V",
52 "sdk":"19",
53 }
54 self.session = requests.Session()
55 # self.session.mount('https://', MyAdapter())
56
57
58 def generate_user(self):
59 with open ("./fanlist_111992.csv", "rb") as csvfile:
60 reader = csv.reader(csvfile)
61 reader.next() # Skip the header row
62 for row in reader:
63 scraped_data = {}
64 scraped_data["country"] = row[0].decode('string-escape').decode("utf-8")
65 scraped_data["nick_name"] = row[2].decode('string-escape').decode("utf-8")
66 scraped_data["photo"] = "./photos"+row[3]+".jpg"
67 handle = list(row[3].decode('string-escape').decode("utf-8")[4:])
68 random.shuffle(handle)
69 scraped_data["handle"] = row[3].decode('string-escape').decode("utf-8")[:4] +''.join(handle)
70 scraped_data["bio"] = row[4].decode('string-escape').decode("utf-8")
71 scraped_data["email"] = scraped_data["handle"]+random.choice(["@newmail.com", "@gmail.com", "@hotmail.com", "@yahoo.com", "@outlook.com"])
72 scraped_data["password"] = scraped_data["handle"][::-1]+random.choice(["1", "2", "3", "4", "5"])
73 yield scraped_data
74
75 def get_likes(self,account, like_counts):
76 return
77
78 def get_follows(self, account, follow_counts):
79 return
80
81 def get_a_phone(self,phone):
82 #random value for imei and mac no
83 imei = ''.join(random.choice('0123456789abcdef') for i in range(8))
84 val = ''.join(random.choice('0123456789ABCDEF') for i in range(12))
85 mac = ':'.join(val[i:i+2] for i in xrange(0, 12, 2))
86 self.signature_data["imei"] = imei
87 self.signature_data["mac"] = mac
88 if phone == "lava":
89 self.common_header["os"] = "android 4.1.2"
90 self.common_header["User-Agent"] = "Musical.ly/2016020601 (Android; LAVA LAVA 4.1.2;rv:16)"
91 self.common_header["build"] = "2016020601"
92 self.common_header["mobile"] = "LAVA Iris 501"
93
94 self.signature_data["app"]["os"] = "android 4.1.2"
95 self.signature_data["model"] = "SM-G730V"
96 self.signature_data["sdk"] = "19"
97
98 elif phone == "samsung":
99 self.common_header["os"] = "android 5.1.1"
100 self.common_header["User-Agent"] = "Musical.ly/2016040101 (Android; Samsung Galaxy J3 5.1.1;rv:22)"
101 self.common_header["build"] = "2016040101"
102 self.common_header["mobile"] = "Samsung Galaxy J3 SM-J320Y"
103
104 self.signature_data["app"]["os"] = "android 5.1.1"
105 self.signature_data["model"] = "SM-J320Y"
106 self.signature_data["sdk"] = "22"
107
108 elif phone == "oneplusone":
109 self.common_header["os"] = "android 5.1.1"
110 self.common_header["User-Agent"] = "Musical.ly/2016040101 (Android; OnePlus A0001 5.1.1;rv:22)"
111 self.common_header["build"] = "2016040101"
112 self.common_header["mobile"] = "OnePlus A0001"
113
114 self.signature_data["app"]["os"] = "android 5.1.1"
115 self.signature_data["model"] = "A0001"
116 self.signature_data["sdk"] = "22"
117
118 elif phone == "nexus":
119 self.common_header["os"] = "android 6.0.1"
120 self.common_header["User-Agent"] = "Musical.ly/2016040101 (Android; LGE Nexus 5 6.0.1;rv:23)"
121 self.common_header["build"] = "2016040101"
122 self.common_header["mobile"] = "LGE Nexus 5"
123
124 self.signature_data["app"]["os"] = "android 6.0.1"
125 self.signature_data["model"] = "Nexus 5"
126 self.signature_data["sdk"] = "22"
127
128 elif phone == "htc":
129 self.common_header["os"] = "android 5.1.1"
130 self.common_header["User-Agent"] = "Musical.ly/2016040101 (Android; HTC One A9 5.1.1;rv:22)"
131 self.common_header["build"] = "2016040101"
132 self.common_header["mobile"] = "HTC One A9"
133
134 self.signature_data["app"]["os"] = "android 5.1.1"
135 self.signature_data["model"] = "A9"
136 self.signature_data["sdk"] = "22"
137 return
138
139 def get_proxy_list(self,country):
140 content = requests.get("http://free-proxy-list.net").text
141 doc = lxml.html.document_fromstring(content)
142 proxy_list = []
143 lines = doc.cssselect('table.fpltable tr')
144 for line in lines:
145 proxy_dict = {}
146 tds = line.cssselect('td')
147 if len(tds) > 7:
148 ip_address, port, country_code, https, sec = tds[0].text, tds[1].text, tds[2].text, tds[6].text, tds[7].text
149 if tds[4].text == "elite proxy" and country_code == country:
150 adres = "%s:%s" % (ip_address, port)
151 proxy_dict["http"] = "http://"+adres
152 proxy_dict["https"] = "https://"+adres
153 # proxy_list.append(proxy_dict)
154 yield proxy_dict
155 yield "No proxy found"
156 # return proxy_list
157
158 def set_proxy(self,country):
159 is_good_proxy = False
160 retries = 0
161 proxies = self.get_proxy_list(country)
162 while retries < 5 and not is_good_proxy:
163 proxy = proxies.next()
164 if proxy == "No proxy found":
165 # Do random stuffs here
166 break
167 self.session.proxies = proxy
168 try:
169 response = self.session.get("http://ipecho.net/plain")
170 is_good_proxy = True
171 except:
172 print 'get error, when checking proxy, try to get next proxy'
173 pass
174 return is_good_proxy
175
176
177 def unset_proxy(self):
178 self.session.proxies = None
179
180 #Function to get siugnature
181 def get_signature(self):
182 payload = {"data": json.dumps(self.signature_data)}
183 print payload
184 response = self.session.get(self.signing_server, data = payload)
185 try:
186 return str(json.loads(response.text)["signature"])
187 except ValueError:
188 return "signature not received"
189
190 #function to generate get request Id
191 def get_unique_id(self):
192 request_id = hashlib.md5(str(random.random())).hexdigest()
193 request_id = request_id[:8]+"-"+request_id[8:12]+"-"+request_id[12:16]+"-"+request_id[16:20]+"-"+request_id[20:]
194 return request_id
195
196 #function for time stamp
197 def get_time_stamp(self):
198 a = time.time()*1000
199 return "%.0f"%a
200
201 def prepare_header(self, url, method):
202 request_id = self.get_unique_id()
203 timestamp = self.get_time_stamp()
204 self.session.headers.clear()
205 self.session.headers = dict(self.common_header)
206 self.session.headers["X-Request-ID"] = request_id
207 self.signature_data["app"]["X-Request-ID"] = request_id
208 self.signature_data["serviceTime"] = timestamp
209 self.signature_data["app"]["method"]=method
210 self.signature_data["app"]["url"]= url
211 request_signature = self.get_signature()
212 self.session.headers["X-Request-Sign2"] = request_signature
213 return
214
215 def prepare_registration_data(self, handle, email, password):
216 user = '''{"handle":"%s","email":"%s","password":"%s"}'''%(handle,email,password)
217 post_url = "http://www.musical.ly/rest/v2/users/register"
218 BOUNDARY = "27c8b11a-9b7e-4849-a665-7f1a04edf2b7"
219 data = (
220 """
221 --%(boundary)s
222 Content-Disposition: form-data; name="user"
223 Content-Type: application/json; charset=utf-8
224 Content-Length: %(content_length)s
225 \r\n%(user)s
226 --%(boundary)s--
227 """ % {
228 "boundary" : BOUNDARY,
229 "content_length" : len(user),
230 "user" : user
231 }).replace("\n", "\r\n") # HTTP uses DOS-style line endings.
232
233 #update current headers
234 self.session.headers["Content-Type"] = "multipart/mixed; boundary=\"%s\"" % BOUNDARY
235 return data
236
237 def register_accounts(self, count):
238 all_users = self.generate_user()
239 for i in xrange(count):
240 user_data = all_users.next()
241 self.get_a_phone(random.choice(self.phone_profiles))
242 country = user_data["country"]
243 proxy = self.set_proxy(country)
244 if not proxy:
245 proxy = self.set_proxy("US")
246 method = "POST"
247 url = "https://www.musical.ly/rest/v2/users/register"
248 self.prepare_header(url,method)
249 handle = user_data["handle"]
250 email = user_data["email"]
251 password = user_data["password"]
252 data = self.prepare_registration_data(handle,email,password)
253 response = self.session.post(url, data = data, headers = self.session.headers)
254 print self.signature_data
255 print self.session.headers
256 print data
257 print response.content
258 print response.status_code