OzoneAsai commited on
Commit
babcb0b
1 Parent(s): e453921

Update scrape_images_worker.py

Browse files
Files changed (1) hide show
  1. scrape_images_worker.py +49 -45
scrape_images_worker.py CHANGED
@@ -5,7 +5,7 @@ import requests
5
  import sys
6
  from PIL import Image, UnidentifiedImageError
7
  from io import BytesIO
8
- os.systems("python3 -m playwright install")
9
  log_file = "app_log.txt" # ログファイルのパス
10
 
11
  # ログフォーマットの定義
@@ -26,147 +26,151 @@ logger = logging.getLogger(__name__)
26
 
27
  # 安全なフォルダ名を生成する関数
28
  def generate_safe_folder_name(url):
29
- # URLから安全なフォルダ名を生成(ファイル名に使えない文字を除去)
30
  safe_name = re.sub(r'[^a-zA-Z0-9_\-]', '_', url)
 
31
  return safe_name
32
 
33
  # 画像を保存する関数 (JPG 80%の品質で保存)
34
  def save_image_as_jpg(image_url, save_folder, image_name):
 
 
35
  if not os.path.exists(save_folder):
 
36
  os.makedirs(save_folder)
37
- logger.info(f"フォルダを作成しました: {save_folder}")
38
 
39
  try:
 
40
  response = requests.get(image_url, timeout=10)
41
  response.raise_for_status() # HTTPエラーが発生した場合例外を投げる
 
42
  except requests.exceptions.RequestException as e:
43
- logger.error(f"画像のダウンロード中にエラーが発生しました: {e}")
44
  return
45
 
46
  try:
 
47
  image = Image.open(BytesIO(response.content))
 
48
  except UnidentifiedImageError:
49
- logger.warning(f"未識別の画像ファイル: {image_url}. スキップします。")
50
  return
51
  except Exception as e:
52
- logger.error(f"画像のオープン中にエラーが発生しました: {e}")
53
  return
54
 
55
- # 保存時に JPG に変換し、品質80%で保存
56
  image_path = os.path.join(save_folder, image_name)
57
  try:
 
58
  image.convert("RGB").save(image_path, "JPEG", quality=80)
59
- logger.info(f"画像を保存しました: {image_path}")
60
  except Exception as e:
61
- logger.error(f"画像の保存中にエラーが発生しました: {e}")
62
 
63
  # 画像の再帰的取得
64
  def scrape_images_by_page(url, folder_name='scraped_images'):
65
- # URL"/"で終わっている場合、スラッシュを削除
66
  original_url = url
67
  url = url.rstrip('/')
68
- logger.info(f"処理するURL: {url}")
69
 
70
  with sync_playwright() as p:
71
- browser = p.chromium.launch(headless=True) # ブラウザを表示して操作
 
72
  page = browser.new_page()
73
 
74
- # 初期ページにアクセス
75
  page.goto(url)
76
- logger.info(f"ページにアクセスしました: {url}")
77
-
78
- # ページが完全に読み込まれるまで待機
79
  page.wait_for_load_state('networkidle')
80
- logger.info("ページの読み込みが完了しました。")
81
 
82
  # lazy-loading属性を無効にするためのJavaScriptを挿入
83
  try:
 
84
  page.evaluate("""
85
  document.querySelectorAll('img[loading="lazy"]').forEach(img => {
86
  img.setAttribute('loading', 'eager');
87
  img.src = img.src; // 画像を強制的にリロード
88
  });
89
  """)
90
- logger.info("lazy-loadingを無効化しました。")
91
  except Exception as eval_error:
92
- logger.warning(f"JavaScriptの評価中にエラーが発生しました: {eval_error}")
93
 
94
- # フォルダ名を生成
95
  safe_folder_name = generate_safe_folder_name(url)
96
  folder_path = os.path.join(folder_name, safe_folder_name)
97
- logger.info(f"保存先フォルダ: {folder_path}")
98
 
99
  # ページ数を取得
100
  try:
101
- # ページ数が格納されているセレクタからテキストを取得
102
  page_count_selector = 'div.tag-container:nth-child(8) > span:nth-child(1) > a:nth-child(1) > span:nth-child(1)'
103
  page_count_text = page.locator(page_count_selector).text_content().strip()
104
  num_pages = int(re.search(r'\d+', page_count_text).group())
105
- logger.info(f"セレクタ '{page_count_selector}' からページ数を取得: {num_pages}")
106
  except Exception as e:
107
- logger.warning(f"セレクタ '{page_count_selector}' からページ数を取得できませんでした: {e}")
108
- # セレクタが見つからない場合のフォールバック
109
  try:
110
  fallback_selector = 'section.reader-bar:nth-child(2) > div:nth-child(2) > button:nth-child(3) > span:nth-child(3)'
111
  page.wait_for_selector(fallback_selector, timeout=5000)
112
  num_pages_text = page.locator(fallback_selector).text_content().strip()
113
  num_pages = int(re.search(r'\d+', num_pages_text).group())
114
- logger.info(f"セレクタ '{fallback_selector}' からページ数を取得: {num_pages}")
115
  except Exception as e2:
116
- logger.error(f"ページ数の取得に失敗しました: {e2}")
117
- num_pages = 1 # デフォルトで1ページとする
118
 
119
- logger.info(f"総ページ数: {num_pages}")
120
 
121
  # 各ページにアクセスして画像を取得
122
  for i in range(1, num_pages + 1):
123
  page_url = f"{url}/{i}"
 
124
  page.goto(page_url)
125
- logger.info(f"ページにアクセスしました: {page_url}")
126
-
127
- # ページが完全に読み込まれるまで待機
128
  page.wait_for_load_state('networkidle')
129
- logger.info(f"ページ {i} の読み込みが完了しました。")
130
 
131
  try:
132
- # 画像を取得するセレクタ
133
  img_selector = '#image-container > a > img'
134
  img_elements = page.locator(img_selector)
135
  img_count = img_elements.count()
136
- logger.info(f"ページ {i} の画像数: {img_count}")
137
 
138
  if img_count == 0:
139
- logger.warning(f"ページ {i} に画像が見つかりません。")
140
  continue
141
 
142
  for j in range(img_count):
143
  try:
 
144
  image_element = img_elements.nth(j)
145
  image_url = image_element.get_attribute('src')
146
  if not image_url:
147
- # data-srcなどに画像URLが格納されている場合
148
  image_url = image_element.get_attribute('data-src')
149
- logger.info(f"取得した画像URL (ページ {i}, 画像 {j + 1}): {image_url}")
150
 
151
  if image_url:
152
- # ファイル名にページ番号と画像番号を含め、位取りを適用
153
  image_name = f'page_{str(i).zfill(5)}_img_{str(j + 1).zfill(5)}.jpg'
154
  save_image_as_jpg(image_url, folder_path, image_name)
155
  except Exception as e:
156
- logger.error(f"ページ {i}, 画像 {j + 1} の処理中にエラーが発生しました: {e}")
157
  continue
158
  except Exception as e:
159
- logger.error(f"ページ {i} の画像取得中にエラーが発生しました: {e}")
160
  continue
161
 
162
  browser.close()
163
- logger.info("ブラウザを閉じました。")
164
 
165
  if __name__ == "__main__":
166
  if len(sys.argv) < 2:
167
- logger.error("使用方��: python scrape_images_worker.py <URL>")
168
  sys.exit(1)
169
 
170
- url = sys.argv[1] # コマンドライン引数でURLを受け取る
171
- folder_name = 'scraped_images' # デフォルトのフォルダ名
 
172
  scrape_images_by_page(url, folder_name)
 
 
5
  import sys
6
  from PIL import Image, UnidentifiedImageError
7
  from io import BytesIO
8
+
9
  log_file = "app_log.txt" # ログファイルのパス
10
 
11
  # ログフォーマットの定義
 
26
 
27
  # 安全なフォルダ名を生成する関数
28
  def generate_safe_folder_name(url):
29
+ logger.info(f"Generating a safe folder name from URL: {url}")
30
  safe_name = re.sub(r'[^a-zA-Z0-9_\-]', '_', url)
31
+ logger.info(f"Generated folder name: {safe_name}")
32
  return safe_name
33
 
34
  # 画像を保存する関数 (JPG 80%の品質で保存)
35
  def save_image_as_jpg(image_url, save_folder, image_name):
36
+ logger.info(f"Saving image from {image_url} to folder: {save_folder} with name: {image_name}")
37
+
38
  if not os.path.exists(save_folder):
39
+ logger.info(f"Folder does not exist, creating new folder: {save_folder}")
40
  os.makedirs(save_folder)
41
+ logger.info(f"Folder created: {save_folder}")
42
 
43
  try:
44
+ logger.info(f"Downloading image from URL: {image_url}")
45
  response = requests.get(image_url, timeout=10)
46
  response.raise_for_status() # HTTPエラーが発生した場合例外を投げる
47
+ logger.info(f"Successfully downloaded image: {image_url}")
48
  except requests.exceptions.RequestException as e:
49
+ logger.error(f"Error occurred during image download: {e}")
50
  return
51
 
52
  try:
53
+ logger.info(f"Opening image from response content")
54
  image = Image.open(BytesIO(response.content))
55
+ logger.info(f"Image successfully opened")
56
  except UnidentifiedImageError:
57
+ logger.warning(f"Unidentified image file from URL: {image_url}. Skipping.")
58
  return
59
  except Exception as e:
60
+ logger.error(f"Error occurred while opening image: {e}")
61
  return
62
 
 
63
  image_path = os.path.join(save_folder, image_name)
64
  try:
65
+ logger.info(f"Converting image to JPEG and saving to {image_path}")
66
  image.convert("RGB").save(image_path, "JPEG", quality=80)
67
+ logger.info(f"Image saved successfully: {image_path}")
68
  except Exception as e:
69
+ logger.error(f"Error occurred while saving image: {e}")
70
 
71
  # 画像の再帰的取得
72
  def scrape_images_by_page(url, folder_name='scraped_images'):
73
+ logger.info(f"Starting image scraping for URL: {url}")
74
  original_url = url
75
  url = url.rstrip('/')
76
+ logger.info(f"Processed URL for scraping: {url}")
77
 
78
  with sync_playwright() as p:
79
+ logger.info(f"Launching Chromium browser in headless mode")
80
+ browser = p.chromium.launch(headless=True) # ブラウザを非表示で起動
81
  page = browser.new_page()
82
 
83
+ logger.info(f"Accessing page: {url}")
84
  page.goto(url)
 
 
 
85
  page.wait_for_load_state('networkidle')
86
+ logger.info(f"Page fully loaded: {url}")
87
 
88
  # lazy-loading属性を無効にするためのJavaScriptを挿入
89
  try:
90
+ logger.info(f"Disabling lazy-loading for images on the page")
91
  page.evaluate("""
92
  document.querySelectorAll('img[loading="lazy"]').forEach(img => {
93
  img.setAttribute('loading', 'eager');
94
  img.src = img.src; // 画像を強制的にリロード
95
  });
96
  """)
97
+ logger.info(f"Lazy-loading disabled")
98
  except Exception as eval_error:
99
+ logger.warning(f"Error occurred during lazy-loading disablement: {eval_error}")
100
 
 
101
  safe_folder_name = generate_safe_folder_name(url)
102
  folder_path = os.path.join(folder_name, safe_folder_name)
103
+ logger.info(f"Images will be saved to: {folder_path}")
104
 
105
  # ページ数を取得
106
  try:
107
+ logger.info(f"Attempting to retrieve number of pages from the website")
108
  page_count_selector = 'div.tag-container:nth-child(8) > span:nth-child(1) > a:nth-child(1) > span:nth-child(1)'
109
  page_count_text = page.locator(page_count_selector).text_content().strip()
110
  num_pages = int(re.search(r'\d+', page_count_text).group())
111
+ logger.info(f"Number of pages found: {num_pages}")
112
  except Exception as e:
113
+ logger.warning(f"Failed to retrieve number of pages from the primary selector: {e}")
 
114
  try:
115
  fallback_selector = 'section.reader-bar:nth-child(2) > div:nth-child(2) > button:nth-child(3) > span:nth-child(3)'
116
  page.wait_for_selector(fallback_selector, timeout=5000)
117
  num_pages_text = page.locator(fallback_selector).text_content().strip()
118
  num_pages = int(re.search(r'\d+', num_pages_text).group())
119
+ logger.info(f"Number of pages found using fallback selector: {num_pages}")
120
  except Exception as e2:
121
+ logger.error(f"Failed to retrieve page count: {e2}. Defaulting to 1 page.")
122
+ num_pages = 1
123
 
124
+ logger.info(f"Starting to scrape {num_pages} pages")
125
 
126
  # 各ページにアクセスして画像を取得
127
  for i in range(1, num_pages + 1):
128
  page_url = f"{url}/{i}"
129
+ logger.info(f"Accessing page: {page_url}")
130
  page.goto(page_url)
 
 
 
131
  page.wait_for_load_state('networkidle')
132
+ logger.info(f"Page {i} fully loaded")
133
 
134
  try:
135
+ logger.info(f"Attempting to locate images on page {i}")
136
  img_selector = '#image-container > a > img'
137
  img_elements = page.locator(img_selector)
138
  img_count = img_elements.count()
139
+ logger.info(f"Found {img_count} images on page {i}")
140
 
141
  if img_count == 0:
142
+ logger.warning(f"No images found on page {i}")
143
  continue
144
 
145
  for j in range(img_count):
146
  try:
147
+ logger.info(f"Processing image {j + 1} on page {i}")
148
  image_element = img_elements.nth(j)
149
  image_url = image_element.get_attribute('src')
150
  if not image_url:
 
151
  image_url = image_element.get_attribute('data-src')
152
+ logger.info(f"Image URL found: {image_url}")
153
 
154
  if image_url:
 
155
  image_name = f'page_{str(i).zfill(5)}_img_{str(j + 1).zfill(5)}.jpg'
156
  save_image_as_jpg(image_url, folder_path, image_name)
157
  except Exception as e:
158
+ logger.error(f"Error processing image {j + 1} on page {i}: {e}")
159
  continue
160
  except Exception as e:
161
+ logger.error(f"Error occurred while retrieving images on page {i}: {e}")
162
  continue
163
 
164
  browser.close()
165
+ logger.info(f"Browser closed")
166
 
167
  if __name__ == "__main__":
168
  if len(sys.argv) < 2:
169
+ logger.error("Usage: python scrape_images_worker.py <URL>")
170
  sys.exit(1)
171
 
172
+ url = sys.argv[1]
173
+ folder_name = 'scraped_images'
174
+ logger.info(f"Script started with URL: {url}")
175
  scrape_images_by_page(url, folder_name)
176
+ logger.info("Script completed")