前提・実現したいこと
現在from concurrent.futures import ThreadPoolExecutorを使用し、スレッド処理にて高速requestsさせているのですがサイト自体を読み込むのに時間がかかりスレッドで複数実行して待機するよりも一つで何個もどんどん投げたほうが効率が良くなるかなと思い書き換えようと思っております。過去にも同様の質問がteratailにされており拝見させていただいたところ本質的な回答はされておらずスレッド処理を推奨していたので質問させていただきます。
この過去の質問と同様の状況でしてかなり情報が散らばっていたり昔の書式で合ったり自分なりにしっかりと調べたつもりでわからなかったので質問させていただいております。ここからは自分なりに調べてなんとなく動作が理解できているところを書かせていただきます。
できるだけ、今のコードを編集せずAsyncioを実装してみようと思い調べたところrequestsはそれ自体がnon blockingではないためrun_in_executor()を使用することで並列的に?requestsでも高速で処理ができるという記事を見ました。
さらにget_event_loop() でイベントループを取得し、run_until_complete()で Futureの完了を待ち、 結果を取得してイベントループをclose()などといったひとつひとつの動作はなんとなくりかいできたのですが書式などがいまいちよくわかりません。
もし、requestsでは非同期処理をすることはできない、やそれよりもaiohttpを使ったほうが速いなども教えていただけると嬉しいです。
また、async/awaitなどの使い方もわかりやすいサイトなどがあれば教えていただけると助かります。
いまいちそこの時点でこんがらがってしまい理解できてない気がするので...
最後に、grequestsも試しましたがなぜか簡単な一リクエストも実行されずお手上げでした。
該当のソースコード
Python3
1import requests 2import json 3import time 4import re 5import os 6import sys 7from bs4 import BeautifulSoup 8from concurrent.futures import ThreadPoolExecutor 9 10if os.path.exists("list.txt"): 11 pass 12else: 13 print("\nエラー:list.txtが存在しません") 14 time.sleep(3) 15 sys.exit() 16 17args = sys.argv 18if len(args) == 2: 19 input_file = args[1] 20else: 21 input_file = "list.txt" 22 23keywords_list = [ 24 "", 25 "", 26 "", 27 "", 28] 29proxies = { 30 "http": "", 31 "https": "", 32} 33ua = "" 34headers = {"User-Agent": ua} 35header = {"Authorization": "Bearer " + ""} 36count = 0 37 38logs = [] 39 40while True: 41 42 start = time.time() 43 44 def check_url(target_url, headers=headers, proxies=proxies, retry=3): 45 46 for i in range(retry): 47 48 try: 49 start = time.time() 50 51 #ここ↓のリクエストが時間がかかるので非同期処理をさせたい 52 53 req = requests.get( 54 target_url, headers=headers, proxies=proxies, allow_redirects=False 55 ) 56 logs.append(str(req.status_code) + "\t" + target_url) 57 target_urlll = re.sub("(.*)(?=/)|/|(?=?)(.*)", "", target_url) 58 print(str(req.status_code) + "\t" + target_urlll) 59 60 if req.status_code == 404: 61 html = BeautifulSoup(req.text, "html.parser") 62 title = html.find("title").text 63 body = html.find("body").text 64 65 for keyword in keywords_list: 66 if keyword in body: 67 68 #ここからのリクエストは非同期処理をさせなくてよいので気にしないでください 69 70 target_url = re.sub( 71 "(.*)(?=/)|/|(?=?)(.*)", "", target_url 72 ) 73 74 r = requests.get( 75 "" 76 + str(target_url) 77 ) 78 jsondata = json.loads(r.text) 79 result = jsondata[""] 80 81 if result == True: 82 print("" + str(target_url)) 83 message = "" + str(target_url) 84 payload = {"message": message} 85 requ = requests.post( 86 "", 87 headers=header, 88 params=payload, 89 ) 90 91 elif "" in r.text: 92 print("" + str(target_url)) 93 94 #ここまで 95 96 break 97 98 elif req.status_code == 200: 99 html = BeautifulSoup(req.text, "html.parser") 100 # print(str(html)) 101 title = html.find("title").text 102 body = html.find("body").text 103 104 for keyword in keywords_list: 105 if keyword in body: 106 107 #ここからのリクエストは非同期処理をさせなくてよいので気にしないでください 108 109 target_url = re.sub( 110 "(.*)(?=/)|/|(?=?)(.*)", "", target_url 111 ) 112 113 r = requests.get( 114 "" 115 + str(target_url) 116 ) 117 jsondata = json.loads(r.text) 118 result = jsondata[""] 119 120 if result == True: 121 print("" + str(target_url)) 122 message = "" + str(target_url) 123 payload = {"message": message} 124 requ = requests.post( 125 "", 126 headers=header, 127 params=payload, 128 ) 129 130 elif "" in r.text: 131 print("" + str(target_url)) 132 133 #ここまで 134 135 break 136 137 return 138 except requests.exceptions.ConnectTimeout: 139 logs.append("TIMEOUT" + "\t" + target_url) 140 time.sleep(10) 141 142 except requests.exceptions.ConnectionError: 143 logs.append("ERROR" + "\t" + target_url) 144 time.sleep(10) 145 146 except requests.exceptions.ChunkedEncodingError: 147 logs.append("ERROR" + "\t" + target_url) 148 time.sleep(10) 149 150 with open("list.txt") as f: 151 urls = f.read().splitlines() 152 153 threads = [] 154 155 with ThreadPoolExecutor(max_workers=()) as pool: 156 threads = [res for res in pool.map(check_url, urls)] 157 158 with open("log.txt", "w") as f: 159 f.write("\n".join(logs)) 160 161 elapsed_time = time.time() - start 162 163 count = count + 1 164 165 print("\nelapsed_time:{0}".format(elapsed_time) + "[sec]\n") 166 print(str(count) + "回目") 167
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー