爬虫類ノート(5)分布式
3153 ワード
単機の下ではマルチスレッドとマルチプロセスを用いて機械の十分な利用を実現することができるが,単機の能力は限られており,より多くの機械を採用すれば爬虫類の効率をさらに向上させることができる.ここでは分布式爬虫類を導入する.分散爬虫類の場合、Redisを使用してタスクキューを実装すると、システム構成が大幅に簡素化されます.
1.Redis入門 Redis redis-serverを起動するサーバ側はredis-serverであり、パラメータなしで直接起動することができる.redis-serverのデフォルトのポート番号は6379で、デフォルトではリモート接続できません.プロファイルを使用することで、デフォルト設定 を変更できます.
bindは指定されたバインドipに使用され、0.0.0.0は任意のリモートまたはローカル接続を受け入れることができ、portはポート番号を指定するために使用されます.接続Redis redis-cliはRedisシステムに付属するクライアントで、パラメータなしで直接起動し、デフォルトのポートの下のローカルRedisサーバに接続できます.-pでポートを指定し、-hでサーバアドレスを指定することもできます. データ型Redisはkey-valueタイプのデータベースとして、valueは複数のデータ型をサポートします. a.文字列文字列はRedisの最も簡単なデータ型であり、keyのタイプはすべて文字列であることに注意する.バイナリデータも文字列です.たとえば、画像ファイルの内容をvalueに存在させることができます.valueの長さは512 MBを超えてはならない.
b.リストRedisリストは双方向チェーンテーブルで下位構造を実現し、前または後から操作することができる.
Redisリストにはブロック操作があり,この操作はプロセス間通信の実現に非常に有用である.rpopとlpopはブロック機能を実現していないので,プロセス間通信の要求を達成するためにはポーリングが必要であり,このような戦略は明らかにだめである.BRPOPとBLPOPはブロック操作を実現し、リストが空の場合、設定された時間になるまでブロックされます.Redisデータ型 Redisサーバ を停止する.
2.分布式爬虫類
分散型爬虫類はメインサーバ(master)とスレーブサーバ(slave)に分けられ、メインサーバはurlをタスクキューに割り当て、リンクデータを受信する.サーバから指定したページを抽出し、データを分析し、データベースにデータを格納し、メインサーバに戻るリンクを担当します.サーバ クライアント
1.Redis入門
bind 0.0.0.0
port 6666
bindは指定されたバインドipに使用され、0.0.0.0は任意のリモートまたはローカル接続を受け入れることができ、portはポート番号を指定するために使用されます.
redis-cli -h localhost -p 6666
>set name 'dongge' #
OK
>get name
"dongge"
>keys * # key
"name"
>set counter 100
OK
>incr counter
(integer)101
>incryby counter 50
(integer)151
>exists name # key
(integer)1
>type name
string
>del name # key
(integer)1
>type name
none
>rpush mylist A #
(integer)1
>rpush mylist B
(integer)2
>lpush mylist C #
(integer)3
>lrange mylist 0 -1
1) "C"
2) "A"
3) "B"
>rpop mylist # lpop
"B"
Redisリストにはブロック操作があり,この操作はプロセス間通信の実現に非常に有用である.rpopとlpopはブロック機能を実現していないので,プロセス間通信の要求を達成するためにはポーリングが必要であり,このような戦略は明らかにだめである.BRPOPとBLPOPはブロック操作を実現し、リストが空の場合、設定された時間になるまでブロックされます.Redisデータ型
redis-cli shutdown (redis-cli -p 6666 -h localhost)
2.分布式爬虫類
分散型爬虫類はメインサーバ(master)とスレーブサーバ(slave)に分けられ、メインサーバはurlをタスクキューに割り当て、リンクデータを受信する.サーバから指定したページを抽出し、データを分析し、データベースにデータを格納し、メインサーバに戻るリンクを担当します.
import redis
def server(init_url):
s = set()#
s.add(init_url)
conn = redis.Redis()
conn.rpush('url',init_url)
while True:
data = conn.brpop('data')
#print data
if data != None and data[0] == 'data':
data = eval(data[1])
urls = data['urls']
for url in urls:
if url not in s:
s.add(url)
conn.rpush('url',url)
if __name__ == '__main__':
server('http://www.qiushibaike.com')
'''
{“urls”:[],"data":[]}
'''
def handlepage(html):
pass
def subprocess(url,host = 'localhost'):
conn = redis.Redis(host)
while True:
url = conn.brpop('url')
html = loadurl(url[1])#
ret = handlepage(html)#
conn.rpush('urls',ret['urls'])# server urls
save(ret['data'])#
def client(num,host='localhost'):
for i in range(num):
p = Process(target = subprocess,args=(host,)
p.start()