Очистка Селена от динамической бесконечной прокрутки без AJAX

#python #selenium #web-scraping

#python #selenium #очистка веб-страниц

Вопрос:

Намерение: Очистить данные компании из списка Inc.5000 (например, ранг, название компании, рост, отрасль, штат, город, описание (путем наведения курсора мыши на название компании)).

Проблема: Из того, что я вижу, данные из списка динамически генерируются в браузере (без AJAX). Кроме того, я не могу просто прокрутить страницу вниз, а затем очистить всю страницу, потому что одновременно доступно только определенное количество компаний. Другими словами, рендерятся компании 1-10, но как только я прокручиваю до компаний 500-510, компании 1-10 «не отображаются».

Текущие усилия: следующий код — это то, над чем я сейчас работаю.

 driver = webdriver.Chrome()
driver.implicitly_wait(30)
driver.get('https://www.inc.com/inc5000/list/2020')

all_companies = []

scroll_max = 600645 #found via Selenium IDE

curr_scroll = 0
next_scroll = curr_scroll 2000

for elem in driver.find_elements_by_class_name('franchise-list__companies'):
    while scroll_num <= scroll_max:
        scroll_fn = ''.join(("window.scrollTo(", str(curr_scroll), ", ", str(next_scroll), ")"))
        driver.execute_script(scroll_fn)
        all_companies.append(elem.text.split('n')) 
        print('Current length: ', len(all_companies))
        curr_scroll  = 2000
        next_scroll  = 2000
  

Большинство сообщений SO, связанных с бесконечной прокруткой, касаются тех, которые либо поддерживают данные, сгенерированные при прокрутке, либо создают AJAX, к которому можно подключиться. Эта проблема является исключением из обоих (но если я пропустил соответствующий пост SO, не стесняйтесь указать мне в этом направлении).

Проблема:

  1. Удаляются избыточные данные (например, одна компания может быть очищена дважды)
  2. Мне все еще нужно разделить данные впоследствии (конечным пунктом назначения является Pandas datafarame)
  3. Не включает описание компании (видно при наведении курсора мыши на название компании)
  4. Это медленно (я понимаю, что это оговорка к самому Selenium, но думаю, что код можно оптимизировать)

Комментарии:

1. проблема 1 — используйте set для обеспечения извлечения уникальных данных и медленно прокручивайте, проблема 2 — создавайте фрейм данных по мере прокрутки, проблема 3 — наведите курсор на каждую компанию, которую вы видите, и сохраните эти данные, прежде чем двигаться дальше, проблема 4 — да, вам придется с этим справиться…

Ответ №1:

Данные загружаются с внешнего URL. Чтобы напечатать все компании, вы можете использовать этот пример:

 import json
import requests


url = 'https://www.inc.com/rest/i5list/2020'
data = requests.get(url).json()

# uncomment this to print all data:
# print(json.dumps(data, indent=4))

for i, company in enumerate(data['companies'], 1):
    print('{:>05d} {}'.format(i, company['company']))
    # the hover text is stored in company['ifc_business_model']
  

С принтами:

 00001 OneTrust
00002 Create Music Group
00003 Lovell Government Services
00004 Avalon Healthcare Solutions
00005 ZULIE VENTURE INC
00006 Hunt A Killer
00007 Case Energy Partners
00008 Nationwide Mortgage Bankers
00009 Paxon Energy
00010 Inspire11
00011 Nugget
00012 TRYFACTA
00013 CannaSafe
00014 BRUMATE
00015 Resource Innovations

...and so on.
  

Комментарии:

1. Андрей, ты можешь рассказать мне, как ты нашел этот URL? Я пытался найти его некоторое время, но, видимо, я искал не в нужном месте (ах) :/

2. @alofgran Я открыл инструменты разработчика Firefox -> вкладку Сеть и заметил, где страница выполняет запросы. Этот URL был самым большим с точки зрения загруженного размера.

3. Что ж… это смущает. Ха-ха. Я сделал именно это в Chrome, но по какой-то причине я пропустил это. Спасибо, Андрей!