Повышение скорости / производительности веб-скребка с множеством исключений - PullRequest
0 голосов
/ 20 ноября 2018

Я написал некоторый веб-код, который в настоящее время работает, но довольно медленно.Немного предыстории: я использую Selenium, так как он требует нескольких этапов кликов и ввода вместе с BeautifulSoup.Мой код просматривает список материалов в подкатегориях на веб-сайте (изображение ниже) и просматривает их.Если материал, скопированный с веб-сайта, относится к числу 30-ти, которые мне интересны (см. Ниже), то он записывает число 1 в кадр данных, который я позже преобразовываю в лист Excel.

Причина, по которой это так медленно, я все равно считаю, заключается в том, что существует множество исключений.Тем не менее, я не уверен, как справиться с этим, кроме как попробовать / кроме.Основные фрагменты кода можно увидеть ниже, так как весь фрагмент кода довольно длинный.Я также приложил изображение рассматриваемого веб-сайта для справки.

lst = ["Household cleaner and detergent bottles", "Plastic milk bottles", "Toiletries and shampoo bottles", "Plastic drinks bottles", 
       "Drinks cans", "Food tins", "Metal lids from glass jars", "Aerosols", 
       "Food pots and tubs", "Margarine tubs", "Plastic trays","Yoghurt pots", "Carrier bags",
       "Aluminium foil", "Foil trays",
       "Cardboard sleeves", "Cardboard egg boxes", "Cardboard fruit and veg punnets", "Cereal boxes", "Corrugated cardboard", "Toilet roll tubes", "Food and drink cartons",
       "Newspapers", "Window envelopes", "Magazines", "Junk mail", "Brown envelopes", "Shredded paper", "Yellow Pages" , "Telephone directories",
       "Glass bottles and jars"]

def site_scraper(site):
    page_loc = ('//*[@id="wrap-rlw"]/div/div[2]/div/div/div/div[2]/div/ol/li[{}]/div').format(site)
    page = driver.find_element_by_xpath(page_loc) 
    page.click()
    driver.execute_script("arguments[0].scrollIntoView(true);", page)

    soup=BeautifulSoup(driver.page_source, 'lxml')
    for i in x:
        for j in y:
            try:
                material = soup.find_all("div", class_ = "rlw-accordion-content")[i].find_all('li')[j].get_text(strip=True).encode('utf-8')
                if material in lst:
                    df.at[code_no, material] = 1 
                else:
                    continue 
                continue
            except IndexError:
                continue

x = xrange(0,8) 
y = xrange(0,9)

p = xrange(1,31)

for site in p:
    site_scraper(site)

В частности, i и j редко переходят на 6,7 или 8, но когда они это делают, важно, чтобы я захватил эту информациютоже.Для контекста, i соответствуют количеству различных категорий на изображении ниже (Автозапчасти, Строительные материалы и т. Д.), В то время как j представляют подсписок (автомобильные аккумуляторы и моторное масло и т. Д.).Поскольку эти два цикла повторяются для всех 30 сайтов для каждого кода, а у меня 1500 кодов, это очень медленно.В настоящее время на 10 кодов уходит 6,5 минуты.

Есть ли способ улучшить этот процесс?Я пытался понять списки, но было трудно справляться с такими ошибками, и мои результаты уже не были точными.Может ли функция «если» быть лучшим выбором для этого, и если да, то как бы я включил ее?Я также был бы рад приложить полный код, если требуется.Спасибо!

enter image description here

РЕДАКТИРОВАТЬ: изменив

        except IndexError:
            continue

на

        except IndexError:
            break

сейчасработает почти вдвое быстрее!Очевидно, что лучше всего выйти из цикла после того, как он выйдет из строя один раз, так как последующие итерации также не пройдутОднако любые другие советы по питону все еще приветствуются:)

1 Ответ

0 голосов
/ 21 ноября 2018

Звучит так, будто вам просто нужен текст этих lis:

lis = driver.execute_script("[...document.querySelectorAll('.rlw-accordion-content li')].map(li => li.innerText.trim())")

Теперь вы можете использовать их для своей логики:

for material in lis:
  if material in lst:
    df.at[code_no, material] = 1
...