Qwentor

Untitled

Mar 12th, 2020
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.28 KB | None | 0 0
  1. import asyncio
  2. import nest_asyncio
  3. import pyppeteer
  4. from pyppeteer import launch
  5. from pprint import pprint
  6. import requests
  7. import base64
  8. import json
  9. import os
  10. import aiofiles
  11. import random
  12. from pyquery import PyQuery as pq
  13. import aiosqlite
  14. from datetime import datetime
  15. import regex
  16. from urllib.parse import urlparse
  17. import idna
  18. import configparser
  19.  
  20. config = configparser.ConfigParser()
  21. config.read('settings.ini')
  22.  
  23. BASEDIR = os.path.dirname(os.path.realpath(__file__))
  24.  
  25. nest_asyncio.apply()
  26.  
  27. def get_as_base64(url):
  28.     return base64.b64encode(requests.get(url).content).decode('utf8')
  29.  
  30.  
  31. def dict_factory(cursor, row):
  32.     d = {}
  33.     for idx, col in enumerate(cursor.description):
  34.         d[col[0]] = row[idx]
  35.     return d
  36.  
  37.  
  38. async def process(query):
  39.  
  40.  
  41.     print('START PROCESS')
  42.  
  43.    
  44.     async with aiofiles.open(os.path.join(BASEDIR, config['PARSER']['Proxies']), mode='r', encoding="utf-8") as f:
  45.         proxies = await f.readlines()
  46.         await f.close()
  47.  
  48.     proxies = [x.strip() for x in proxies if x != '']
  49.     proxy = random.choice(proxies)
  50.  
  51.  
  52.     print('TEST')
  53.     browser = await launch(headless=False, args=['--no-sandbox', '--proxy-server='+proxy, ])
  54.     print(browser)
  55.     print(4)
  56.     # try:
  57.     page = await browser.newPage()
  58.     await page.authenticate({ 'username': config['PARSER']['Login'], 'password': config['PARSER']['Password'] })
  59.     await page.setJavaScriptEnabled(False)
  60.     # await page.setViewport({'width': 1200, 'height': 4000})
  61.    
  62.  
  63.     await page.setRequestInterception(True)
  64.  
  65.     async def intercept(request):
  66.         try:
  67.             if any(request.resourceType == _ for _ in ('image', 'script')):
  68.                 await request.abort()
  69.             else:
  70.                 await request.continue_()
  71.         except pyppeteer.errors.NetworkError as e:
  72.             print(e)
  73.  
  74.     page.on('request', lambda req: asyncio.ensure_future(intercept(req)))
  75.    
  76.  
  77.     await page.goto('https://yandex.ru', {'timeout': 100000})
  78.     print("AFTER GOTO")
  79.     # await page.waitFor(4000)
  80.     # await page.waitForNavigation()
  81.     await page.focus('input[name=text]')
  82.     await page.keyboard.type(query),
  83.     await page.keyboard.press("Enter")
  84.     # await page.waitFor(4000)
  85.     await page.waitForNavigation({'timeout': 100000})
  86.     print(5)
  87.     html = await page.content()
  88.     d = pq(html)
  89.     captcha_input = d("input[name=rep]")
  90.  
  91.     # captcha_input = await page.evaluate("() => document.querySelector('input[name=rep]')")
  92.  
  93.     if len(captcha_input):
  94.         captcha_lnk = d('div.captcha__image img').attr('src')
  95.         # captcha_lnk = await page.evaluate("() => document.querySelector('div.captcha__image img').src")
  96.         print(captcha_lnk)
  97.         b64pic = get_as_base64(captcha_lnk)
  98.  
  99.         url = 'http://'+config['PARSER']['CapMonster']+'/createTask'
  100.         print(url)
  101.  
  102.         task = {
  103.             "clientKey": "dce6bcbb1a728ea8d563de6d169a2057",
  104.             "task": {
  105.                 "type": "ImageToTextTask",
  106.                 "body": b64pic,
  107.                 "phrase": False,
  108.                 "case": False,
  109.                 "numeric": False,
  110.                 "math": 0,
  111.                 "minLength": 0,
  112.                 "maxLength": 0
  113.             }
  114.         }
  115.         print(6)
  116.  
  117.         r = requests.post(url, data=json.dumps(task))
  118.         res = r.json()
  119.         print(res)
  120.         taskId = res['taskId']
  121.  
  122.         # await page.waitFor(4000)
  123.  
  124.         url2 = 'http://'+config['PARSER']['CapMonster']+'/getTaskResult'
  125.  
  126.         task2 = {
  127.             "clientKey": "dce6bcbb1a728ea8d563de6d169a2057",
  128.             "taskId": taskId
  129.         }
  130.  
  131.         r = requests.post(url2, data=json.dumps(task2))
  132.         res = r.json()
  133.         print(res)
  134.         if 'solution' in res.keys():
  135.             rep = res['solution']['text']
  136.         else:
  137.             await page.close()
  138.             await browser.close()
  139.             return (query, False)
  140.         print(7)
  141.         await page.focus('input[name=rep]')
  142.         await page.keyboard.type(rep)
  143.         await page.keyboard.press("Enter")
  144.         # await page.waitFor(3000)
  145.         await page.waitForNavigation({'timeout': 100000})
  146.  
  147.         html = await page.content()
  148.         d = pq(html)
  149.         captcha_input = d("input[name=rep]")
  150.  
  151.         # captcha_input = await page.evaluate("() => document.querySelector('input[name=rep]')")
  152.         if len(captcha_input):
  153.             print('wrong capcha')
  154.             await page.close()
  155.             await browser.close()
  156.             # await tasks.add(loop.create_task(process(query)))
  157.             return (query, False)
  158.  
  159.         else:
  160.             html = await page.content()
  161.             d = pq(html)
  162.             page1 = d("li.serp-item")
  163.             print('len', len(page1))
  164.  
  165.             if not len(page1):
  166.                 await page.close()
  167.                 await browser.close()
  168.                 return (query, False)
  169.  
  170.             sites = []
  171.             for item in page1:
  172.                 d = pq(item)
  173.                 label = d("div.label")
  174.                
  175.                 if len(label):
  176.                     if label.text() == 'реклама':
  177.                         site = d('a.link_theme_outer > b').text()
  178.                         if regex.search(r'\p{IsCyrillic}', site) is not None:
  179.                             link = d('a.link_theme_outer').attr('href')
  180.                             result = regex.search(r'market\.yandex\.ru', link)
  181.                             if result is not None:
  182.                                 continue
  183.                             print(query, link)
  184.                             r = requests.get(link, allow_redirects=True)
  185.                             content = r.text
  186.                             result = regex.search(r'\;URL=\'.*\'', content)
  187.                             if result is not None:
  188.                                 url = result.group(0)[6:-1]
  189.                                 site = urlparse(url).hostname
  190.                                 site = idna.decode(site)
  191.  
  192.  
  193.                         sites.append(site)
  194.  
  195.             print(sites)
  196.  
  197.             if not len(sites):
  198.                 await page.close()
  199.                 await browser.close()
  200.                 return (query, False)
  201.  
  202.             print(8)
  203.            
  204.             now = int(datetime.timestamp(datetime.now()))
  205.  
  206.             async with aiosqlite.connect(os.path.join(BASEDIR, config['PARSER']['Database'])) as db:
  207.                
  208.                 cursor = await db.execute("""INSERT INTO results (`text`, sites, updated, busy, file)  VALUES('{t}', '{s}', {u}, {b}, '{f}') ON CONFLICT(`text`)  DO UPDATE SET sites=excluded.sites, updated=excluded.updated, busy=excluded.busy, file=excluded.file""".format(t=query, s=json.dumps(sites), u=now, b=1, f='984.txt'))
  209.                 await db.commit()
  210.  
  211.             print('DONE COMPLETE')
  212.             # await page.screenshot({'path': query+'.png'})
  213.             await page.close()
  214.             await browser.close()
  215.             return (query, True)
  216.  
  217.     else:
  218.         html = await page.content()
  219.         d = pq(html)
  220.         page1 = d("li.serp-item")
  221.         print('len', len(page1))
  222.  
  223.         if not len(page1):
  224.             await page.close()
  225.             await browser.close()
  226.             return (query, False)
  227.  
  228.         print(9)
  229.  
  230.         sites = []
  231.         for item in page1:
  232.             d = pq(item)
  233.             label = d("div.label")
  234.            
  235.             if len(label):
  236.                 if label.text() == 'реклама':
  237.                     site = d('a.link_theme_outer > b').text()
  238.                     if regex.search(r'\p{IsCyrillic}', site) is not None:
  239.                         link = d('a.link_theme_outer').attr('href')
  240.                         print(query, link)
  241.                         result = regex.search(r'market\.yandex\.ru', link)
  242.                         if result is not None:
  243.                             continue
  244.                         r = requests.get(link, allow_redirects=True)
  245.                         content = r.text
  246.                         # print(query, content)
  247.                         result = regex.search(r'\;URL=\'.*\'', content)
  248.                         if result is not None:
  249.                             url = result.group(0)[6:-1]
  250.                             site = urlparse(url).hostname
  251.                             site = idna.decode(site)
  252.  
  253.                     sites.append(site)
  254.  
  255.         print(sites)
  256.         if not len(sites):
  257.             await page.close()
  258.             await browser.close()
  259.             return (query, False)
  260.  
  261.         now = int(datetime.timestamp(datetime.now()))
  262.  
  263.         async with aiosqlite.connect(os.path.join(BASEDIR, config['PARSER']['Database'])) as db:
  264.            
  265.             cursor = await db.execute("""INSERT INTO results (`text`, sites, updated, busy, file)  VALUES('{t}', '{s}', {u}, {b}, '{f}') ON CONFLICT(`text`)  DO UPDATE SET sites=excluded.sites, updated=excluded.updated, busy=excluded.busy, file=excluded.file""".format(t=query, s=json.dumps(sites), u=now, b=1, f=config['PARSER']['Queries']))
  266.            
  267.             await db.commit()
  268.    
  269.         print('DONE COMPLETE')
  270.         # await page.screenshot({'path': query+'.png'})
  271.         await page.close()
  272.         await browser.close()
  273.         return (query, True)
  274.  
  275.     # except (pyppeteer.errors.TimeoutError, pyppeteer.errors.PageError, pyppeteer.errors.NetworkError, pyppeteer.errors.ElementHandleError) as e:
  276.     #   print(e)
  277.     #   await browser.close()
  278.     #   # await tasks.add(loop.create_task(process(query)))
  279.     #   return (query, False)
  280.  
  281.  
  282.  
  283. async def main(loop):
  284.     print("STARTED")
  285.     async with aiofiles.open(os.path.join(BASEDIR, config['PARSER']['Queries']), mode='r', encoding="utf-8") as f:
  286.         queries = await f.readlines()
  287.         await f.close()
  288.  
  289.  
  290.     print(1)
  291.  
  292.     queries = [x.strip() for x in queries if x != '']
  293.     random.shuffle(queries)
  294.  
  295.     tasks = set()
  296.     no_concurrent = 5
  297.  
  298.     for query in queries:
  299.  
  300.         notdone = [task for task in tasks.copy() if not task.done()]
  301.  
  302.         if len(notdone) >= no_concurrent:
  303.             _done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  304.  
  305.         while True:
  306.             try:
  307.                 # await asyncio.wait(tasks)
  308.                 flag = True
  309.                
  310.                 print(2)
  311.  
  312.                 tmp = [task for task in tasks.copy() if task.done()]
  313.                 t = {}
  314.  
  315.                 for task in tmp:
  316.                     if task.result()[0] not in t.keys():
  317.                         t[task.result()[0]] = task
  318.                     elif task.result()[1]:
  319.                         t[task.result()[0]] = task
  320.  
  321.                 tmp = t.values()
  322.  
  323.                 for task in tmp:
  324.                     print(task.result())
  325.                     if not task.result()[1]:
  326.                         if len(tasks) >= no_concurrent:
  327.                             _done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  328.                         flag = False
  329.                         tasks.add(loop.create_task(process(task.result()[0])))
  330.  
  331.                 if flag:
  332.                     break
  333.  
  334.             except ValueError as e:
  335.                 break
  336.  
  337.        
  338.         tasks.add(loop.create_task(process(query)))
  339.  
  340.     await asyncio.wait(tasks)
  341.  
  342.  
  343.    
  344.     while True:
  345.         flag = True
  346.  
  347.         tmp = [task for task in tasks.copy() if task.done()]
  348.         t = {}
  349.  
  350.         print(3)
  351.  
  352.         for task in tmp:
  353.             if task.result()[0] not in t.keys():
  354.                 t[task.result()[0]] = task
  355.             elif task.result()[1]:
  356.                 t[task.result()[0]] = task
  357.  
  358.         tmp = t.values()
  359.  
  360.         for task in tmp:
  361.             print(task.result())
  362.             if not task.result()[1]:
  363.                 notdone = [task for task in tasks.copy() if not task.done()]
  364.                 if len(notdone) >= no_concurrent:
  365.                     _done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  366.                 flag = False
  367.                 print('3!!!!', task)
  368.                 tasks.add(loop.create_task(process(task.result()[0])))
  369.  
  370.         await asyncio.wait(tasks)
  371.  
  372.         if flag:
  373.             break
  374.  
  375.     async with aiosqlite.connect(os.path.join(BASEDIR, config['PARSER']['Database'])) as db:
  376.         db.row_factory = dict_factory
  377.         sql = "SELECT * FROM results"
  378.         cursor = await db.execute(sql)
  379.         rows = await cursor.fetchall()
  380.        
  381.         for i in range(len(rows)):
  382.             rows[i]['sites'] = json.loads(rows[i]['sites'])
  383.  
  384.  
  385.  
  386.  
  387.  
  388. while True:
  389.     loop = asyncio.new_event_loop()
  390.     asyncio.set_event_loop(asyncio.new_event_loop())
  391.     loop = asyncio.get_event_loop()
  392.     loop.run_until_complete(main(loop))
  393.     loop.close()
Advertisement
Add Comment
Please, Sign In to add comment