python aiohttpを利用して非同期爬虫類を作る
4256 ワード
まず、一般的な方法で実装されている爬虫類、すなわち同期方法を見てみましょう.完全なPythonコードは以下の通りです.
同時方式でベストセラーになる図書情報を這い出す
出力結果は次のとおりです.
プログラムは23.5秒実行され、500冊の本の情報を取得しましたが、効率はまあまあです.
次にaiohttpで作成した非同期爬虫類の効率を見てみましょう.完全なソースコードは以下の通りです.
この爬虫類は従来の一般的な方法の爬虫類の考え方や処理方法とほぼ一致しているが,HTTPリクエストを処理する際にaiohttpモジュールを用い,ページを解析する際に関数がコヒーレントになりaysncioを再利用して同時処理を行うことで爬虫類の効率を向上させることは間違いない.実行結果は次のとおりです.
以上から,同期法と非同期法で作製した爬虫類の効率は大きく異なることが分かるので,実際に爬虫類を作製する過程で,aysncio,aiohttpのような非同期モジュールを多く利用することも考えられる.また、aiohttpは3.5.3以降のPythonバージョンのみサポートされています.
同時方式でベストセラーになる図書情報を這い出す
import time
import requests
import pandas as pd
from bs4 import BeautifulSoup
'''
?Python :821460695 , , !
'''
# table
table = []
#
def download(url):
html = requests.get(url).text
# BeautifulSoup HTML
soup = BeautifulSoup(html, "lxml")
#
book_list = soup.find('ul', class_="bang_list clearfix bang_list_mode")('li')
for book in book_list:
info = book.find_all('div')
# , , , ,
rank = info[0].text[0:-1]
name = info[2].text
comments = info[3].text.split(' ')[0]
author = info[4].text
date_and_publisher = info[5].text.split()
publisher = date_and_publisher[1] if len(date_and_publisher) >= 2 else ''
# table
table.append([rank, name, comments, author, publisher])
#
urls = ['http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-%d' % i for i in range(1, 26)]
#
print('#' * 50)
t1 = time.time() #
for url in urls:
download(url)
# table pandas DataFrame CSV
df = pd.DataFrame(table, columns=['rank', 'name', 'comments', 'author', 'publisher'])
df.to_csv('E://douban/dangdang.csv', index=False)
t2 = time.time() #
print(' , :%s' % (t2 - t1))
print('#' * 50)
出力結果は次のとおりです.
##################################################
, :23.522345542907715
##################################################
プログラムは23.5秒実行され、500冊の本の情報を取得しましたが、効率はまあまあです.
次にaiohttpで作成した非同期爬虫類の効率を見てみましょう.完全なソースコードは以下の通りです.
import time
import aiohttp
import asyncio
import pandas as pd
from bs4 import BeautifulSoup
# table
table = []
# ( )
async def fetch(session, url):
async with session.get(url) as response:
return await response.text(encoding='gb18030')
#
async def parser(html):
# BeautifulSoup HTML
soup = BeautifulSoup(html, "lxml")
#
book_list = soup.find('ul', class_="bang_list clearfix bang_list_mode")('li')
for book in book_list:
info = book.find_all('div')
# , , , ,
rank = info[0].text[0:-1]
name = info[2].text
comments = info[3].text.split(' ')[0]
author = info[4].text
date_and_publisher = info[5].text.split()
publisher = date_and_publisher[1] if len(date_and_publisher) >=2 else ''
# table
table.append([rank,name,comments,author,publisher])
#
async def download(url):
async with aiohttp.ClientSession() as session:
html = await fetch(session, url)
await parser(html)
#
urls = ['http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-%d'%i for i in range(1,26)]
#
print('#' * 50)
t1 = time.time() #
# asyncio IO
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(download(url)) for url in urls]
tasks = asyncio.gather(*tasks)
loop.run_until_complete(tasks)
# table pandas DataFrame CSV
df = pd.DataFrame(table, columns=['rank','name','comments','author','publisher'])
df.to_csv('E://douban/dangdang.csv',index=False)
t2 = time.time() #
print(' aiohttp, :%s' % (t2 - t1))
print('#' * 50)
この爬虫類は従来の一般的な方法の爬虫類の考え方や処理方法とほぼ一致しているが,HTTPリクエストを処理する際にaiohttpモジュールを用い,ページを解析する際に関数がコヒーレントになりaysncioを再利用して同時処理を行うことで爬虫類の効率を向上させることは間違いない.実行結果は次のとおりです.
##################################################
aiohttp, :2.405137538909912
##################################################
以上から,同期法と非同期法で作製した爬虫類の効率は大きく異なることが分かるので,実際に爬虫類を作製する過程で,aysncio,aiohttpのような非同期モジュールを多く利用することも考えられる.また、aiohttpは3.5.3以降のPythonバージョンのみサポートされています.