Rumah > Artikel > pembangunan bahagian belakang > Bagaimana untuk menggunakan pengaturcaraan serentak dalam perangkak Python
Pengaturcaraan serentak merujuk kepada reka bentuk program yang boleh melaksanakan berbilang operasi dalam tempoh masa Ia biasanya diwakili oleh berbilang tugas dalam program yang dimulakan pada masa yang sama dan boleh berlari dan berinteraksi antara satu sama lain. Faedah pengaturcaraan serentak ialah ia dapat meningkatkan prestasi dan responsif program.
Atur cara crawler ialah tugasan intensif I/O biasa, I/O berbilang benang dan tak segerak merupakan pilihan yang baik. kerana apabila bahagian tertentu program disekat kerana operasi I/O, bahagian lain program masih boleh berjalan, jadi kita tidak perlu membuang banyak masa menunggu dan menyekat.
Mari kita lihat versi benang tunggal bagi program perangkak. Program perangkak ini menggunakan pustaka requests
untuk mendapatkan data JSON dan menyimpan imej secara setempat melalui fungsi open
.
""" example04.py - 单线程版本爬虫 """ import os import requests def download_picture(url): filename = url[url.rfind('/') + 1:] resp = requests.get(url) if resp.status_code == 200: with open(f'images/beauty/{filename}', 'wb') as file: file.write(resp.content) def main(): if not os.path.exists('images/beauty'): os.makedirs('images/beauty') for page in range(3): resp = requests.get(f'<https://image.so.com/zjl?ch=beauty&sn=>{page * 30}') if resp.status_code == 200: pic_dict_list = resp.json()['list'] for pic_dict in pic_dict_list: download_picture(pic_dict['qhimg_url']) if __name__ == '__main__': main()
Pada sistem macOS atau Linux, kita boleh menggunakan perintah time
untuk memahami masa pelaksanaan kod di atas dan penggunaan CPU, seperti yang ditunjukkan di bawah.
time python3 example04.py
Berikut ialah hasil kod perangkak satu benang yang dilaksanakan pada komputer saya.
python3 example04.py 2.36s pengguna sistem 0.39s 12% cpu 21.578 jumlah
Di sini kita hanya perlu memberi perhatian kepada jumlah masa kod iaitu 21.578
saat, kadar Penggunaan CPU 12%
.
Kami menggunakan teknologi kumpulan benang yang dinyatakan sebelum ini untuk mengubah suai kod di atas kepada versi berbilang benang.
""" example05.py - 多线程版本爬虫 """ import os from concurrent.futures import ThreadPoolExecutor import requests def download_picture(url): filename = url[url.rfind('/') + 1:] resp = requests.get(url) if resp.status_code == 200: with open(f'images/beauty/{filename}', 'wb') as file: file.write(resp.content) def main(): if not os.path.exists('images/beauty'): os.makedirs('images/beauty') with ThreadPoolExecutor(max_workers=16) as pool: for page in range(3): resp = requests.get(f'<https://image.so.com/zjl?ch=beauty&sn=>{page * 30}') if resp.status_code == 200: pic_dict_list = resp.json()['list'] for pic_dict in pic_dict_list: pool.submit(download_picture, pic_dict['qhimg_url']) if __name__ == '__main__': main()
Laksanakan arahan yang ditunjukkan di bawah.
time python3 example05.py
Hasil pelaksanaan kod adalah seperti berikut:
python3 example05.py 2.65s pengguna 0.40 s system 95% cpu 3.193 total
Kami menggunakan aiohttp
untuk mengubah suai kod di atas kepada versi I/O tak segerak. Untuk mencapai pemerolehan sumber rangkaian dan operasi penulisan fail dalam I/O tak segerak, kami mesti memasang perpustakaan pihak ketiga aiohttp
dan aiofile
dahulu.
pip install aiohttp aiofile
Berikut ialah versi I/O tak segerak bagi kod perangkak.
""" example06.py - 异步I/O版本爬虫 """ import asyncio import json import os import aiofile import aiohttp async def download_picture(session, url): filename = url[url.rfind('/') + 1:] async with session.get(url, ssl=False) as resp: if resp.status == 200: data = await resp.read() async with aiofile.async_open(f'images/beauty/{filename}', 'wb') as file: await file.write(data) async def main(): if not os.path.exists('images/beauty'): os.makedirs('images/beauty') async with aiohttp.ClientSession() as session: tasks = [] for page in range(3): resp = await session.get(f'<https://image.so.com/zjl?ch=beauty&sn=>{page * 30}') if resp.status == 200: pic_dict_list = (await resp.json())['list'] for pic_dict in pic_dict_list: tasks.append(asyncio.ensure_future(download_picture(session, pic_dict['qhimg_url']))) await asyncio.gather(*tasks) if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(main())
Laksanakan arahan yang ditunjukkan di bawah.
time python3 example06.py
Hasil pelaksanaan kod adalah seperti berikut:
python3 example06.py 0.92s pengguna 0.27 s system 290% cpu 0.420 total
Berbanding dengan versi single-threaded program perangkak, masa pelaksanaan versi multi-threaded dan versi I/O tak segerak bagi program perangkak telah dipertingkatkan dengan ketara, dan versi I/O tak segerak mempunyai peningkatan ketara dalam masa pelaksanaan Versi /O perangkak berprestasi terbaik.
Atas ialah kandungan terperinci Bagaimana untuk menggunakan pengaturcaraan serentak dalam perangkak Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!