シングルスレッドの非同期マルチタスクコルーチンを達成するために

+シングルスレッドの非同期マルチタスクコルーチン:


意味:データクロールの効率を高めるために、我々はまた、スレッドプールを使用することができます

爬虫類非同期モード:

  • マルチスレッド/マルチプロセス(あまりにも多くのコンピュータ、オープン制御されていない方法はありません)が推奨されていません
  • プール:プールがオープンする任意のスレッドやプロセスではありません。
  • +シングルスレッドマルチタスク非同期コルーチン(推奨)(500のコルーチン、最適)

コンセプト:

コルーチン:?使用することができます取得する方法を基本的にオブジェクト、コルーチンオブジェクト、asynicこの時間は、関数は特殊な関数が呼び出されたとき、その特殊な関数と呼ばれる関数定義を変更するための鍵は、あなたが協力を返すことができますチェンは、文の内部関数は(時間の実行サイクル後)すぐに達成されることはありませんときだけ、オブジェクトに関する特別なコルーチンを返さない、オブジェクト導入モジュールimport asycio

import asyncio
#特殊函数:
async  def test(num):
        print(num)
c = test(10)
print(c)
#内部函数语句没有被执行,返回的是一个协程对象,一个地址,仅仅一个协程对象没有意义

1565053666398

タスクオブジェクト

  • パッケージはコルーチンオブジェクトが変装して、特殊なタスクオブジェクト機能に等しいされた後は、基本的にさらに包装コルーチンオブジェクトです。
  • コールバックに結合するタスク・オブジェクト:add_done_callback(コールバック)時間ループは、コールバック関数の実装が完了する前に実行されます。
import asyncio
#特殊函数:
async  def test(num):
        print(num)
c = test(10)
#内部函数语句没有被执行,返回的是一个协程对象,一个地址,仅仅一个协程对象没有意义

#进行封装,根据一个协程对象封装一个任务对象
task = asyncio.ensure_future(c)

1565053977269

バインドのコールバック:

import asyncio
import time

async def request(url):
          print('正在请求:',url)
          time.sleep(2)
          print('请求完成':url)
          return url

        
#定义一个任务对象的回调函数:
#task参数就是该函数被绑定的任务对象,必须要有.
def task_callback(task):
    print('a callback')
    print(task)
    print(task.result())
#task.result()返回的是特殊函数内部的返回值.



c1 = request('www.qq.com')#协程对象
c2 = request('www.qq.com')
c3 = request('www.qq.com')
task_A = asyncio.ensure_future(c1)
task_B = asyncio.ensure_future(c2)
task_C = asyncio.ensure_future(c3)#任务对象

#绑定回调:函数请求完毕后调用
#只传回调函数的名字,没有传递参数,task就是参数,
task.add_done_callback(task_callback)


#创建时间循环对象
loop = asyncio.get_event_loop()
#将任务对象注册到事件循环对象中并且开启事件循环
loop.run_until_complete(task_A)#放协程对象会是可以的,肯定不会把协程对象直接注册到事件循环

イベントサイクルは(eventloop)。私たちはイベントループタスクオブジェクトオブジェクトに登録する必要があり、イベントループオブジェクトを開く無限ループオブジェクト(実行回数は何回、障害物に遭遇した回数を決定することができません)。

イベントループのターンの後、a,b,cシングルスレッドの場合に実行するサイクルを始めている、そこにブロックされます、それは時間がかかりますが、非同期のイベントループは、タスクオブジェクトを実行するためにコアイベントループオブジェクトです非同期に基づいてオブジェクトが阻止ハングを行うことが判明したとき、 、オブジェクトを同時にBの実装を開始ブロック、B cは障害物の顔を行いますが、閉塞が完了すると、この時間は、彼は、cを実行するために処理が完了した後、などの実装に直接移動します。(2が実行されました回、そのタスクオブジェクトの数とは何の関係も)

import asyncio
import time

async def request(url):
          print('正在请求:',url)
          time.sleep(2)
          print('请求完成':url)

c1 = request('www.qq.com')#协程对象
c2 = request('www.qq.com')
c3 = request('www.qq.com')
task_A = asyncio.ensure_future(c1)
task_B = asyncio.ensure_future(c2)
task_C = asyncio.ensure_future(c3)#任务对象

#创建事件循环对象
loop = asyncio.get_event_loop()
#将任务对象注册到时间循环对象中并且开启事件循环
loop.run_until_complete(task_A)#放协程对象会是可以的,肯定不会把协程对象直接注册到事件循环

キーワード:

await

電流遮断は、引き渡すするときにcpuハングアップする、それのコントロールを。

注意事項:

  • 特別な機能は、モジュールのコード内に表示することはできません非同期をサポートしていません。
  • 内部の特殊な機能がブロッキング操作を検出した、ハング手動でそれらを待たなければなりません。
  • あなたがイベントループに複数のタスクを登録したい場合は、複数のタスクオブジェクトはリストに入れなければなりません、あなたは、タスクリストにwaitメソッドが中断されます使用する必要があります。

マルチタスク非同期コルーチンオブジェクト:

import asyncio
import time

#在特殊函数内部不可以出现不支持异步模块相关的代码.time模块不支持异步,
async def request(url):
          print('正在请求:',url)
          #time.sleep(2)
          #阻塞之后挂起,手动的设置
          await asyncio.sleep(2)
          print('请求完成':url)
          return url
urls = [
    'www.goo.com',
    'www.sss.com',
    'www.sss.com',
    'www.sss.com',
]

def task_callback(task):
    print(task.result())
    
tasks = []
for url in urls:
    c = request(url)
    task = asyncio.ensure_future(cc)
    task.add_done_callback(task_callback)
    task.append(task)#装进一个列表内
    
    
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))#将任务列表中的任务对象进行挂起操作
    

requestsモジュールは、非同期サポートしていませんので、我々は、モジュールが非同期サポートを導入しますaiohttp

aiohttpモジュール:非同期ネットワーク要求モジュールをサポートし、pip install aiohttp

import asyncio
import time
import aiohttp
start = time.time()


#在特殊函数内部不可以出现不支持异步模块相关的代码
#简单的框架:在此基础上补充细节
async def request(url):
        with aiohttp.ClientSession() as s:
            #s.get/post和requests中的get/post用法几乎一样:url,headers,data/params
            #在s.get中如果使用代理操作:proxy = 'http://ip:port'
            with s.get(url) as response:
                #获取字符串类型的响应数据:response.text()
                #获取byte类型:response.read()
                page_text = response.text()
                return page_text
#细节1:在每一个with前加上async关键字
#细节2:在get方法前和response.text()前加上await关键字进行手动挂起操作

#真实代码:
async def request(url):
    async with aiohttp.ClientSession() as s:
       async with await s.get(url) as response:
        page_text = await response.text()
        return page_text
urls = []
for i in range(500):
    urls.append('https://127.0.0.1:5000/bobo')

def parse(task):
    page_text = task.result()
    print(page_text+',请求数据')
    
tasks =[]
for url in urls:
    c = request(url)
    task = asyncio.ensure_future(c)
    task.add_done_callback(parse)
    tasks.append(task)
    
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(time.time()-start)
    

aiohttpケース:

import aiohttp
import asyncio
from lxml import etree

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}

async def request(url):
    async with aiohttp.ClientSession() as s:
        async with await s.get(url,headers=headers) as response:
            page_text = await response.text()
            return page_text

urls = []
all_titles = []
url = 'http://wz.sun0769.com/index.php/question/reply?page=%d'
for page in range(10):
    u_page = page*30
    new_url = format(url%u_page)
    urls.append(new_url)

def parse(task):
    page_text = task.result()#page_text
    tree = etree.HTML(page_text)
    tr_list = tree.xpath('/html/body/div[4]/table[2]//tr')
    for tr in tr_list:
        title = tr.xpath('./td[2]/a[1]/text()')[0]
        print(title)
        all_titles.append(title)
    
tasks = []
for url in urls:
    c = request(url)#协程对象
    task = asyncio.ensure_future(c)#封装成任务对象
    task.add_done_callback(parse)
    tasks.append(task)
    
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
    
    

async

selenium基本的な使用:

コンセプト:ブラウザベースの自動化モジュール。

セレンと爬虫類との間の関連性:成功したランディングページをクロールすることができた後、シミュレートされた着陸を達成するために、データの動的ロードをキャプチャするのは非常に簡単。

環境の使用:

セレンをインストールするPIP

ドライバーは、ブラウザをダウンロード

ブラウザオブジェクトを作成します。

from  selenium import webdriver


bro = webdriver.Chrome(executable_path = 'chromedriver.exe')#驱动程序路径

#发起指定url请求
bro.get('http:www.baidu.com')

#再搜索框中搜索

#可以使用find系列方法标签定位
bro.find_element_by_xpath('//*[@id="key"]')

#向搜索框中写入商品名称
search_input.send_keys('iphone')
sleep(2)
btn = bro.find_element_by_xpath('//*[@id="search"]/div/div[2]/button')

btn.click()
sleep(2)

bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
sleep(2)
bro.execute_script('window.scrollTo(0,-document.body.scrollHeight)')
page_text = bro.page_source
with open('./jd.html','w',encoding='utf-8')as p:
    p.write(page_text)
#关闭浏览器
bro.quit()

アクションチェーン:

あなたは連続ビヘイビアアクションの.actionchainsのシリーズをトリガしたい場合

from selenium import webdriver
from selenium.webdriver import ActionChains #动作连
from time import sleep

bro = webdriver.Chrome(executable_path='chromedriver.exe')
bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')

#定位要拖动的标签
#定位的标签是存在于iframe的子页面中,如果直接使用find做定位,是定位不到的
# target_ele = bro.find_element_by_id('draggable')

#像定位iframe中子页面中的标签必须进行如下操作
bro.switch_to.frame('iframeResult')
target_ele = bro.find_element_by_id('draggable')

#基于动作连实现滑动操作
action = ActionChains(bro)
#点击且长按
action.click_and_hold(target_ele)

for i in range(5):
    #perform()表示立即执行动作连指定好的动作
    action.move_by_offset(17,0).perform()
    sleep(0.5)

action.release()

sleep(4)

bro.quit()

おすすめ

転載: www.cnblogs.com/Zhao159461/p/11310834.html