私は最近遊んでいて、いつも目に見えない力が私の周りに残っていて、私をたるませて無気力にします。
しかし、私のようなプロの倫理観を持った社交的な動物は、どうして仕事中に眠り、居眠りをすることができるのでしょうか? 。 。 。
突然、私の隣のIOSの同僚が尋ねました。「ねえ、兄弟、ウェブサイトの写真がとても面白いと思いました。それらを保存して、開発のインスピレーションを向上させるのを手伝ってくれませんか? '
強い社会的な動物として、どうして私はそれができないと言うことができますか?その時、私は考えずに同意しました:「ああ、それは簡単です。私を数分待ってください。」
同僚から提供された写真のウェブサイトをクリックし、
ウェブサイトは次のようになります。
数十ページをめくった後、突然少し気分が高揚しました。 「いや、学びに来なかったの?」と心の中で思いました。しかし、美しい女性の写真を見ることは、学習とどのように関連しているのでしょうか?」
一生懸命考えた後、突然、「パイソンなしでクローラーを書いて、このウェブサイトからすべての写真を一度に入手したい」と頭に浮かびました。
あなたが言うことをして、自分でやって、どちらのクローラーが良いか尋ねてください、「人生は短いです、私はpythonを使います」。
まず、半年前にダウンロードしたpythonインストールパッケージを自分のコンピューターで見つけ、インストールをクリックし続けました。環境をインストールした後、Webページの構造を簡単に分析しました。クローラーの簡単なバージョンから始めましょう
# ミスアイの写真を撮ってローカルに保存する
import requests
from lxml import etree as et
import os
# リクエストヘッダー
headers ={
# ユーザーエージェント
' User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
# クロールするページのベースアドレス
base_url =''
# 写真を保存するための基本的なパス
base_dir ='D:/python/code/aixjj/'
# 画像を保存する
def savePic(pic_url):
# ディレクトリが存在しない場合は、新しいディレクトリを作成します
if not os.path.exists(base_dir):
os.makedirs(base_dir)
arr = pic_url.split('/')
file_name = base_dir+arr[-2]+arr[-1]print(file_name)
# 画像コンテンツを取得する
response = requests.get(pic_url, headers = headers)
# 絵を書く
withopen(file_name,'wb')as fp:for data in response.iter_content(128):
fp.write(data)
# このWebサイトは合計62ページしかないため、62回ループすることに注意してください。
for k inrange(1,63):
# リクエストページアドレス
url = base_url+str(k)
response = requests.get(url = url, headers = headers)
# ステータスコードのリクエスト
code = response.status_code
if code ==200:
html = et.HTML(response.text)
# ページ上のすべての写真のアドレスを取得します
r = html.xpath('//li/a/img/@src')
# 次のページのURLを取得する
# t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]for pic_url in r:
a ='http:'+pic_url
savePic(a)print('最初%dページの写真がダウンロードされました'%(k))print('The End!')
クローラーを実行してみてください、ねえ、私はそれが機能するとは思っていませんでした:
しばらくすると、隣の男がまたやって来ました。「やあ、大丈夫ですが、スピードが遅すぎます。長い間待つと、インスピレーションが失われてしまいます。改善してもらえますか? '
クローラーの効率を向上させる方法は?考えてみると、同社のコンピューターは優れたクアッドコアCPUであるか、マルチプロセスバージョンを試してみてください。その後、次のマルチプロセスバージョンが作成されました
# マルチプロセスバージョン-ミスアイの写真をつかんでローカルに保存する
import requests
from lxml import etree as et
import os
import time
from multiprocessing import Pool
# リクエストヘッダー
headers ={
# ユーザーエージェント
' User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
# クロールするページのベースアドレス
base_url =''
# 写真を保存するための基本的なパス
base_dir ='D:/python/code/aixjj1/'
# 画像を保存する
def savePic(pic_url):
# ディレクトリが存在しない場合は、新しいディレクトリを作成します
if not os.path.exists(base_dir):
os.makedirs(base_dir)
arr = pic_url.split('/')
file_name = base_dir+arr[-2]+arr[-1]print(file_name)
# 画像コンテンツを取得する
response = requests.get(pic_url, headers = headers)
# 絵を書く
withopen(file_name,'wb')as fp:for data in response.iter_content(128):
fp.write(data)
def geturl(url):
# リクエストページアドレス
# url = base_url+str(k)
response = requests.get(url = url, headers = headers)
# ステータスコードのリクエスト
code = response.status_code
if code ==200:
html = et.HTML(response.text)
# ページ上のすべての写真のアドレスを取得します
r = html.xpath('//li/a/img/@src')
# 次のページのURLを取得する
# t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]for pic_url in r:
a ='http:'+pic_url
savePic(a)if __name__ =='__main__':
# クロールするリンクのリストを取得する
url_list =[base_url+format(i)for i inrange(1,100)]
a1 = time.time()
# プロセスプールメソッドを使用してプロセスを作成します。デフォルトで作成されるプロセスの数です。=コンピューター監査
# 自分でプールするプロセスの数を定義する=Pool(4)
pool =Pool()
pool.map(geturl,url_list)
pool.close()
pool.join()
b1 = time.time()print('営業時間:',b1-a1)
試してみるという精神で、マルチプロセスバージョンのクローラーを実行しましたが、彼はそれが再び機能することを期待していませんでした。優れたクアッドコアCPUのサポートにより、クローラーの速度は3〜4倍に向上しました。
しばらくすると、バディは再び頭を向けました。「あなたはずっと速いですが、それは最も理想的な状態ではありません。一瞬で180枚の写真をクロールできますか?結局のところ、私のインスピレーションは来ます。 「Sも速く行く」
私:'…'
静かにGoogleを開き、クローラーの効率を向上させる方法を検索して、結論を出します。
マルチプロセス:集中的なCPUタスクでマルチコアCPUリソース(サーバー、多数の並列コンピューティング)を最大限に活用する必要がある場合は、マルチプロセスを使用します。
マルチスレッド:集中的なI / Oタスク(ネットワークI / O、ディスクI / O、データベースI / O)にはマルチスレッドを使用するのが適切です。
ああ、これはI / Oを多用するタスクではありませんか?最初にマルチスレッドクローラーを作成します。したがって、3番目の段落が生まれました:
import threading #スレッドモジュールのインポート
from queue import Queue #キューモジュールをインポートします
import time #タイムモジュールをインポートする
import requests
import os
from lxml import etree as et
# リクエストヘッダー
headers ={
# ユーザーエージェント
' User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
# クロールするページのベースアドレス
base_url =''
# 写真を保存するための基本的なパス
base_dir ='D:/python/code/aixjj/'
# 画像を保存する
def savePic(pic_url):
# ディレクトリが存在しない場合は、新しいディレクトリを作成します
if not os.path.exists(base_dir):
os.makedirs(base_dir)
arr = pic_url.split('/')
file_name = base_dir+arr[-2]+arr[-1]print(file_name)
# 画像コンテンツを取得する
response = requests.get(pic_url, headers = headers)
# 絵を書く
withopen(file_name,'wb')as fp:for data in response.iter_content(128):
fp.write(data)
# クロール記事の詳細ページ
def get_detail_html(detail_url_list, id):while True:
url = detail_url_list.get() #Queueのgetメソッドは、キューから要素を抽出するために使用されます
response = requests.get(url = url, headers = headers)
# ステータスコードのリクエスト
code = response.status_code
if code ==200:
html = et.HTML(response.text)
# ページ上のすべての写真のアドレスを取得します
r = html.xpath('//li/a/img/@src')
# 次のページのURLを取得する
# t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]for pic_url in r:
a ='http:'+pic_url
savePic(a)
# 記事リストページをクロールする
def get_detail_url(queue):for i inrange(1,100):
# time.sleep(1) #遅延1秒、シミュレーションは記事の詳細をクロールするよりも高速です
# Queueキューのputメソッドは、要素をQueueキューに配置するために使用されます。Queueはfirst-in-first-outキューであるため、最初に配置されたURLも最初に取得されます。
page_url = base_url+format(i)
queue.put(page_url)print("put page url {id} end".format(id = page_url))#記事を入手したURLを印刷する
# メイン機能
if __name__ =="__main__":
detail_url_queue =Queue(maxsize=1000) #Queueを使用して、サイズが1000のスレッドセーフなファーストインファーストアウトキューを構築します
# スレッドはリストのURLをクロールする責任があります
thread = threading.Thread(target=get_detail_url, args=(detail_url_queue,))
html_thread=[]
# さらに、写真の取得を担当する3つのスレッドを作成します
for i inrange(20):
thread2 = threading.Thread(target=get_detail_html, args=(detail_url_queue,i))
html_thread.append(thread2)#BCDスレッドクロール記事の詳細
start_time = time.time()
# 4つのスレッドを開始します
thread.start()for i inrange(20):
html_thread[i].start()
# すべてのスレッドが終了するのを待ちます、スレッド.join()この関数は、子スレッドが完了するまで親プロセスがブロックされていることを表します。
thread.join()for i inrange(20):
html_thread[i].join()print("last time: {} s".format(time.time()-start_time))#4つのABCDスレッドがすべて終了した後、メインプロセスで合計クロール時間が計算されます。
大まかなテストの後、私は結論に達しました:「なんてことだ、これは速すぎる」。
同僚のQQポートレートの顔に、マルチスレッドバージョンのクローラーを次のテキストとともにスローします。
これまでに、pythonで画像を自動ダウンロードする方法の例に関するこの記事を紹介しました。関連するpython自動ダウンロード画像については、ZaLou.Cnの以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後、ZaLouをさらにサポートしていただければ幸いです。 Cn!
Recommended Posts