Python Соскоб изображения - PullRequest
1 голос
/ 24 апреля 2020

Здравствуйте, я новичок в python и в рамках своей диссертации я пытаюсь создать большой корпус данных обучения для глубокого обучения.

Мой код работает на conda 3.7 и работает очень хорошо, пока я не попытаюсь получить более 80 изображений. В моем случае мне понадобится пара сотен картинок.

Это python код

import selenium
from selenium import webdriver 
from selenium.webdriver.common.by import By
import requests
from bs4 import BeautifulSoup
import time
import io
import os
from PIL import Image
import hashlib

def fetch_image_urls(query:str, max_links_to_fetch:int, wd:webdriver, sleep_between_interactions:int=1):
    def scroll_to_end(wd):
        wd.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(sleep_between_interactions)    

    # build the google query
    search_url = "https://www.google.com/search?safe=off&site=&tbm=isch&source=hp&q={q}&oq={q}&gs_l=img"

    # load the page
    wd.get(search_url.format(q=query))

    image_urls = set()
    image_count = 0
    results_start = 0
    while image_count < max_links_to_fetch:
        scroll_to_end(wd)

        # get all image thumbnail results
        thumbnail_results = wd.find_elements_by_css_selector("img.Q4LuWd")
        number_results = len(thumbnail_results)

        print(f"Found: {number_results} search results. Extracting links from {results_start}:{number_results}")

        for img in thumbnail_results[results_start:number_results]:
            # try to click every thumbnail such that we can get the real image behind it
            try:
                img.click()
                time.sleep(sleep_between_interactions)
            except Exception:
                continue

            # extract image urls    
            actual_images = wd.find_elements_by_css_selector('img.n3VNCb')
            for actual_image in actual_images:
                if actual_image.get_attribute('src') and 'http' in actual_image.get_attribute('src'):
                    image_urls.add(actual_image.get_attribute('src'))

            image_count = len(image_urls)

            if len(image_urls) >= max_links_to_fetch:
                print(f"Found: {len(image_urls)} image links, done!")
                break
        else:
            print("Found:", len(image_urls), "image links, looking for more ...")
            time.sleep(1)
            return
            load_more_button = wd.find_element_by_css_selector(".mye4qd")
            if load_more_button:
                wd.execute_script("document.querySelector('.mye4qd').click();")

        # move the result startpoint further down
        results_start = len(thumbnail_results)

    return image_urls

def persist_image(folder_path:str,url:str):
    try:
        image_content = requests.get(url).content

    except Exception as e:
        print(f"ERROR - Could not download {url} - {e}")

    try:
        image_file = io.BytesIO(image_content)
        image = Image.open(image_file).convert('RGB')
        file_path = os.path.join(folder_path,hashlib.sha1(image_content).hexdigest()[:10] + '.jpg')
        with open(file_path, 'wb') as f:
            image.save(f, "JPEG", quality=85)
        print(f"SUCCESS - saved {url} - as {file_path}")
    except Exception as e:
        print(f"ERROR - Could not save {url} - {e}")

# As soon as number of images is over 80 Error is shown
def search_and_download(search_term:str,target_path='./images',number_images=170):
    target_folder = os.path.join(target_path,'_'.join(search_term.lower().split(' ')))

    if not os.path.exists(target_folder):
        os.makedirs(target_folder)

    with webdriver.Chrome() as wd:
        res = fetch_image_urls(search_term, number_images, wd=wd, sleep_between_interactions=0.5)

    for elem in res:
        persist_image(target_folder,elem)


#Change here to modify the search query

search_term = 'Hecht'

search_and_download(
    search_term = search_term,
)

И ошибка в журнале

Найдено: 93 изображений ссылки, ищите больше ...

Traceback (последний последний вызов):

Файл "C: \ Users \ Пользователь \ Рабочий стол \ Scraping \ image-collectioning-selenium \ scrapy2 .py ", строка 103, в search_term = search_term,

Файл" C: \ Users \ Пользователь \ Рабочий стол \ Scraping \ image-collectioning-selenium \ scrapy2.py ", строка 94, в search_and_download для Элемент в res: TypeError: объект 'NoneType' не повторяется

1 Ответ

2 голосов
/ 24 апреля 2020

Вы пытаетесь перебрать res, но это None. Вот почему выдается ошибка.

Добавьте условие if:

if res:
    for elem in res:
       persist_image(target_folder,elem)

или добавьте пустой список в эту строку:

res = fetch_image_urls(search_term, number_images, wd=wd, sleep_between_interactions=0.5) or []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...