bs4で画像のURLを取得する方法が解らないです。
これに関しては質問文のソースコードでurl_listでURLを取得できているので、ダウンロードの仕方と保存の仕方が分からないと判断しました。
極論を言えば以下のコードでも可能かと。
Python
1import os
2
3for s in url_list:
4 res = requests.get(s)
5 file_name = os.path.basename(s)
6 with open(file_name, 'wb') as f:
7 f.write(res.content)
※超初心者です。
うーん、少し悩みましたが、ソースコードを頑張って読み取ってくれることを期待して。
クラス | 役割 |
---|
MyFrame | 画面 |
DownLoader | ダウンロード処理 |
Python
1# -*- coding: utf-8 -*-
2from concurrent.futures import ThreadPoolExecutor, as_completed
3from io import BytesIO
4import os
5from pathlib import Path
6from threading import Thread
7from time import sleep
8#おまじない
9import urllib #URLエンコード用
10import bs4 #HTMl解析
11import requests #URlアクセス?
12import re #正規表現(URL抽出)
13import tkinter as tk #GUI
14#import ui #GUI作成
15
16
17class MyFrame(tk.Frame):
18 def __init__(self, root):
19 super().__init__(root)
20 self.pack()
21
22 # ロゴ?を表示
23 # image1 = tk.PhotoImage(file = 'LOGO.gif')
24 # tk.Label(frame1, image = image1).pack()#.grid(row=0, column=0)
25 # ※検索キーワードのテキストボックスを作成
26 self.key_word = tk.StringVar(value='草')
27 self.txt_key_word = tk.Entry(self, textvariable=self.key_word)
28 self.txt_key_word.pack()
29 # 探すボタンを作成
30 serch = tk.Button(self, text='探す', padx=45, pady=7, command=self.search)
31 serch.pack()
32 # 空白
33 tk.Label(self, text="").pack()
34 # オプションボタンを作成
35 option = tk.Button(self, text='設定', padx=44, pady=7) # 微調整しているため、padxの値がちょっとおかしい
36 option.pack()
37 # 空白
38 tk.Label(self, text="").pack()
39 # バグ連絡
40 bug = tk.Button(self, text="バグ・要望等連絡", padx=15, pady=7)
41 bug.pack()
42 # 空白
43 tk.Label(self, text="").pack()
44 # 終了ボタンを作成
45 owa = tk.Button(self, text="終了", padx=46, pady=7, command=self.owari)
46 owa.pack()
47
48 def search(self):
49 search_word = self.key_word.get()
50 # ※画面をブロックさせないためにスレッドを生成して、startを呼び出す。
51 t = Thread(target=hack, args=(search_word,))
52 t.start()
53
54 def owari(self):
55 quit()
56
57
58class DownLoader(object):
59 def __init__(self):
60 # ミリ秒に変換
61 self.interval = 500 / 1000
62 # sec
63 self.timeout = 10
64 self.download_dir = Path('download')
65 self.download_dir.mkdir(exist_ok=True)
66
67 def get(self, url: str, params: dict=None):
68 # 実際のリクエスト処理はここ
69 res = requests.get(url, params=params, timeout=self.timeout)
70 print(res.url)
71 # http ステータスコードが200番台以外なら例外を発生させる。
72 # 存在しないwebページをurlに指定すると例外が発生するので分かりやすいかと。
73 res.raise_for_status()
74 return res
75
76 def get_content(self, url: str, params: dict=None):
77 sleep(self.interval)
78 res = self.get(url, params)
79 return BytesIO(res.content), res.headers['content-type']
80
81 def request(self, url_list: list) ->None:
82 """
83 internet -- (Get) --> local
84 use ThreadPoolExecutor
85 """
86 count = 0
87 with ThreadPoolExecutor() as executor:
88 future_to_url = {executor.submit(self.get_content, url): url for url in url_list}
89 for future in as_completed(future_to_url):
90 url = future_to_url[future]
91 try:
92
93 # get_contentの戻り値はここで取得
94 buffer, content_type = future.result()
95 # 保存対象のファイルかどうか。
96 if not self.save_content_type(content_type):
97 continue
98 # 保存ファイル名はURLのパス部分をそのまま取得
99 # 重複が発生するので連番を付けたりして対応してくださいな。
100 file_name = self.download_dir / os.path.basename(url)
101
102 print(content_type, file_name)
103 # 保存
104 self.save_file(buffer, file_name)
105 count += 1
106 except Exception as ex:
107 print(f"url:{url}, {ex}")
108
109 if count == 0:
110 print(f'save file Empty')
111
112 def save_content_type(self, content_type: str) ->bool:
113 is_saved = ["image/jpeg", "image/png", "image/gif"]
114 return content_type.lower() in is_saved
115
116 def save_file(self, buffer: BytesIO, file_name: Path) ->None:
117 with file_name.open('wb') as f:
118 f.write(buffer.getvalue())
119
120
121# ※Downloaderクラスのインスタンスを生成
122dl = DownLoader()
123
124
125#ダウンロード用(HTML)関数
126def hack(search_word: str): #wordeで取得したURLから画像のURLを抜き出す(解析) 使用ライブラリ:bs4
127 url = 'https://search.yahoo.co.jp/image/search'
128 params = {'n': '60', 'p': search_word, 'search.x': '1'}
129 res = dl.get(url, params)
130 print(res.text)
131 soup = bs4.BeautifulSoup(res.text, "html.parser") #わかんね
132 elems = soup.select('a') #aタグを選択
133 url_list = [] #URLを格納するリストやで
134 for img in elems: #URL取得やで
135 url_list.append(img.get('href'))
136 #print (url_list)
137 print(url_list)
138 kazu = (len(url_list)) #判定
139
140 #print (kazu)
141
142 if kazu == 0: #URL数が0だった時、エラーを出す。
143 error = "urlzeroerror"
144 # ※即座に抜けて、if文のネストを減らす
145 return
146 tdo = url_list
147 # ※リスト内の重複を削除
148 url_list = list(set(url_list))
149 # ※url_listの内容に対してリクエスト!
150 dl.request(url_list)
151
152
153def main() ->None:
154 root = tk.Tk()
155 # ウィンドウのタイトルを設定
156 root.title("フリー画像ダウンローダ -ver1.0_beta")
157 # ウィンドウの大きさを指定
158 root.geometry("800x500")
159 f = MyFrame(root)
160 root.mainloop()
161
162
163if __name__ == '__main__':
164 main()
165
◇参考情報
0. 17.4. concurrent.futures – 並列タスク実行
0. MIME タイプ
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/22 07:19
2018/04/22 07:39
2018/04/22 08:34 編集
2018/04/22 13:18
2018/04/22 13:20
2018/04/22 13:22
2018/04/22 13:23
2018/04/22 13:26
2018/04/22 13:26
2018/04/22 13:31
2018/04/22 13:33
2018/04/22 13:35
2018/04/22 13:36
2018/04/22 13:36
2018/04/22 13:38
2018/04/22 13:40
2018/04/22 13:44
2018/04/22 13:48
2018/04/22 13:54