Отправить форму, которая динамически отображается с помощью Scrapy?

Я пытаюсь отправить динамически созданную форму входа пользователя с помощью Scrapy, а затем проанализировать HTML на странице, которая соответствует успешному логину.

Мне было интересно, как я могу это сделать с помощью Scrapy или комбинации Scrapy и Selenium. Selenium позволяет найти элемент на DOM, но мне было интересно, можно ли «вернуть контроль» в Scrapy после получения полного HTML-кода, чтобы позволить ему выполнять подачу формы и сохранять необходимые файлы cookie , данные сеанса и т. д., чтобы очистить страницу.

По сути, единственная причина, по которой я считал, что Selenium был необходим, – это то, что мне нужна страница для рендеринга из Javascript, прежде чем Scrapy ищет элемент <form> . Однако есть ли альтернативы этому?

Спасибо!

Изменить: этот вопрос похож на этот , но, к сожалению, принятый ответ касается библиотеки Requests вместо Selenium или Scrapy. Хотя этот сценарий может быть возможен в некоторых случаях (см. Это, чтобы узнать больше ), как указывает alecx, Selenium может потребоваться, если «части страницы [такие как формы] загружаются через вызовы API и вставлены на страницу с помощью кода javascript, выполняемого в браузере ».

One Solution collect form web for “Отправить форму, которая динамически отображается с помощью Scrapy?”

Scrapy самом деле не очень подходит для сайта coursera, поскольку он чрезвычайно асинхронен. Части страницы загружаются через вызовы API и вставляются на страницу с помощью кода JavaScript, выполняемого в браузере. Scrapy не является браузером и не может справиться с этим.

Что поднимает вопрос – почему бы не использовать общедоступный API Coursera ?

Помимо документированных, есть другие конечные точки, которые вы можете увидеть, вызванные в инструментах разработчика браузера – вам нужно пройти аутентификацию, чтобы иметь возможность использовать их. Например, если вы вошли в систему, вы можете просмотреть список выбранных курсов:

введите описание изображения здесь

Существует вызов конечной точки memberships.v1 .

Для примера, давайте начнем selenium , войдите в систему и возьмите куки с помощью get_cookies() . Затем давайте получим Request to memberships.v1 endpoint, чтобы получить список архивных курсов, предоставляющих файлы cookie, которые у нас есть из selenium :

 import json import scrapy from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC LOGIN = 'email' PASSWORD = 'password' class CourseraSpider(scrapy.Spider): name = "courseraSpider" allowed_domains = ["coursera.org"] def start_requests(self): self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.get('https://www.coursera.org/login') form = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@data-js='login-body']//div[@data-js='facebook-button-divider']/following-sibling::form"))) email = WebDriverWait(form, 10).until(EC.visibility_of_element_located((By.ID, 'user-modal-email'))) email.send_keys(LOGIN) password = form.find_element_by_name('password') password.send_keys(PASSWORD) login = form.find_element_by_xpath('//button[. = "Log In"]') login.click() WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//h2[. = 'My Courses']"))) self.driver.get('https://www.coursera.org/') cookies = self.driver.get_cookies() self.driver.close() courses_url = 'https://www.coursera.org/api/memberships.v1' params = { 'fields': 'courseId,enrolledTimestamp,grade,id,lastAccessedTimestamp,role,v1SessionId,vc,vcMembershipId,courses.v1(display,partnerIds,photoUrl,specializations,startDate,v1Details),partners.v1(homeLink,name),v1Details.v1(sessionIds),v1Sessions.v1(active,dbEndDate,durationString,hasSigTrack,startDay,startMonth,startYear),specializations.v1(logo,name,partnerIds,shortName)&includes=courseId,vcMembershipId,courses.v1(partnerIds,specializations,v1Details),v1Details.v1(sessionIds),specializations.v1(partnerIds)', 'q': 'me', 'showHidden': 'false', 'filter': 'archived' } params = '&'.join(key + '=' + value for key, value in params.iteritems()) yield scrapy.Request(courses_url + '?' + params, cookies=cookies) def parse(self, response): data = json.loads(response.body) for course in data['linked']['courses.v1']: print course['name'] в import json import scrapy from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC LOGIN = 'email' PASSWORD = 'password' class CourseraSpider(scrapy.Spider): name = "courseraSpider" allowed_domains = ["coursera.org"] def start_requests(self): self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.get('https://www.coursera.org/login') form = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@data-js='login-body']//div[@data-js='facebook-button-divider']/following-sibling::form"))) email = WebDriverWait(form, 10).until(EC.visibility_of_element_located((By.ID, 'user-modal-email'))) email.send_keys(LOGIN) password = form.find_element_by_name('password') password.send_keys(PASSWORD) login = form.find_element_by_xpath('//button[. = "Log In"]') login.click() WebDriverWait(self.driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//h2[. = 'My Courses']"))) self.driver.get('https://www.coursera.org/') cookies = self.driver.get_cookies() self.driver.close() courses_url = 'https://www.coursera.org/api/memberships.v1' params = { 'fields': 'courseId,enrolledTimestamp,grade,id,lastAccessedTimestamp,role,v1SessionId,vc,vcMembershipId,courses.v1(display,partnerIds,photoUrl,specializations,startDate,v1Details),partners.v1(homeLink,name),v1Details.v1(sessionIds),v1Sessions.v1(active,dbEndDate,durationString,hasSigTrack,startDay,startMonth,startYear),specializations.v1(logo,name,partnerIds,shortName)&includes=courseId,vcMembershipId,courses.v1(partnerIds,specializations,v1Details),v1Details.v1(sessionIds),specializations.v1(partnerIds)', 'q': 'me', 'showHidden': 'false', 'filter': 'archived' } params = '&'.join(key + '=' + value for key, value in params.iteritems()) yield scrapy.Request(courses_url + '?' + params, cookies=cookies) def parse(self, response): data = json.loads(response.body) for course in data['linked']['courses.v1']: print course['name'] 

Для меня он печатает:

 Algorithms, Part I Computing for Data Analysis Pattern-Oriented Software Architectures for Concurrent and Networked Software Computer Networks 

Это доказывает, что мы можем предоставить Scrapy файлы cookie из selenium и успешно извлекать данные из страниц «только для входа в систему».


Кроме того, убедитесь, что вы не нарушаете правила из Условий использования , а именно:

Кроме того, в качестве условия доступа к Сайтам вы соглашаетесь не … (c) использовать любые крупные, автоматизированные или электронные средства для доступа к Сайтам (включая, помимо прочего, роботы, пауки, скрипты или инструменты для веб-скрепок );

  • selenium.common.exceptions.WebDriverException: Сообщение: соединение отказано
  • Обращение с полем «Требуется проверка подлинности» с помощью Python 2.7 + Selenium Webdriver
  • Использование селена в фоновом режиме
  • Keys.ESCAPE в selenium webdriver (python)
  • «Firefox неожиданно завершается». При запуске основного сценария Selenium в Python
  • Использование Углового JS (Протрактор) с селеном в Python
  • Selenium, выбор элемента внутри <span>
  • размещение, ввод значения в текстовое поле с использованием селена и питона
  • Python - лучший язык программирования в мире.