Python クローラー: クローラーの効率を向上させる非同期の方法

Python マルチスレッド構文

最初の方法

from threading import Thread
t = Thread(target=fuc) 
t.start()  #多线程状态可以为开始工作状态,具体执行时间由CPU决定

別の方法

class MyThread(Thread):
   def run(self):
     XXXXXX
t = MyThread()
t.start()

Python マルチプロセス構文 (一般的には使用されません)

from multiprocessing import Process
p = Process(tarfet=func)
p.start()

スレッドプールとプロセスプール

スレッド プール: 一度にいくつかのスレッドを開き、ユーザーがタスクをスレッド プールに直接送信すると、スレッド タスクのスケジューリングがスレッド プールに渡されて完了します。

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

with ThreadPoolExecutor(50) as t:
    for i in range(100):
       t.submit(fn,name=XXXX)

例: スレッド プールを使用して郵便教育データ情報をクロールする

アイデア:

1. 1 ページ分のデータを抽出する

2. スレッド プールを使用して複数のページを同時にクロールする
コード:

import requests
from lxml import etree
import csv
import time
from concurrent.futures import ThreadPoolExecutor
f = open("book2.csv",mode="w",newline='')
csvwriter = csv.writer(f)

def download_one_page(url):
    resp = requests.get(url)
    # print(resp.text)
    html = etree.HTML(resp.text)
    divs = html.xpath("/html/body/div[3]/div/div/div/div/ul/li/div[2]")
    for div in divs:
        name = div.xpath("./h4/a/text()")[0]
        # print(name)
        author = div.xpath("./div/span/text()")[0].strip()
        # print(author)
        price = div.xpath("./span/span/text()")[0].strip("¥")
        # print(price)
        csvwriter.writerow([name, author, price])

        time.sleep(1)

    resp.close()
if __name__ == '__main__':
    with ThreadPoolExecutor(50) as t:
        for i in range(0,38):
            t.submit(download_one_page,f"https://www.ryjiaoyu.com/tag/details/7/?page={i}")
    print("over!")
    f.close()

コルーチン

コルーチン: プログラムが IO 操作に遭遇すると、他のタスクに選択的に切り替えることができます。

Python はコルーチンを記述します

import asyncio
async def func1():
 XXXX
async def fucn2():
 XXXX
async def fucn3():
 XXXX

async def main():
 # g = func()    #此时函数是异步协程函数,此时函数执行得到的是一个协程对象
 tasks = [
 asyncio.create_task(func1())
 asyncio.create_task(func2())
 asyncio.create_task(func3())
 ]
 await asyncio.wait(tasks)
 
if __name__ == '__main__':
 asyncio.run(main())

非同期操作のスリープ

 await asyncio.sleep(3) #异步操作时的代码

爬虫類への応用

async def download(url):
    print("loading")
    ## 异步操作的网络请求
    print("over")
    
async def main():
    urls = [
      "XXXX",
      "XXXX",
      “XXXXX"
    ]
    
    tasks = []
    for url in urls:
        d = download(url)
        tasks.append(d)
    await asyncio.wait(tasks)
    
    
if __name__ == '__main__':
   asyncio.run(main())

非同期操作のネットワーク リクエスト

インストール

pip install aiohttp

Python はネットワーク リクエストを書き込みます

import asyncio
import aiohttp

urls = [
   "XXXXX"
   "XXXXX"
   "XXXXX"
]

async def aiodownload(url):
   async with aiohttp.ClientSession() as session:
   # session.get() <==> requests.get()
   # session.post()<==> requests.post()
       async with session.get(url) as resp:
           resp.text()
           # 写入文件
           with open(name,mode="wb") as f:
               f.write(await resp.content.read()) #读取的是异步内容,需要await挂起
   
async def main():
    tasks = []
    for url in urls:
       tasks.append(aiodownload(url))
    await asyncio.wait(tasks)
    
if __name__ == '__main__':
   asyncio.run(main())

Supongo que te gusta

Origin blog.csdn.net/Ohh24/article/details/127716090
Recomendado
Clasificación