Отправить форму, которая динамически отображается с помощью 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) использовать любые крупные, автоматизированные или электронные средства для доступа к Сайтам (включая, помимо прочего, роботы, пауки, скрипты или инструменты для веб-скрепок );

  • Proxy + Selenium + PhantomJS не может изменять User-Agent
  • WebDriver - Python - Сколько элементов в раскрывающемся меню
  • Найти следующий элемент родственного в Python Selenium?
  • Как отправить текст в невидимое поле ввода
  • Python, Selenium: «Элемент больше не привязан к DOM»
  • Python Selenium Alert - запрашивать имя пользователя и пароль не работает
  • Как найти_element_by_link_text при наличии: Исключение NoSuchElement?
  • Не удается открыть IE с использованием селена в python
  • Использование chromedriver с селеном / python / ubuntu
  • Python и как получить текст из объекта WebElement объекта Selenium?
  • Assert / VerifyElementPresent с Python и WebDriver?
  •  
    Interesting Posts for Van-Lav

    Пуассоновский точечный процесс в Matlab

    Reimport модуль в python, в то время как интерактивный

    pandas – получить последнее значение определенного столбца, проиндексированного другим столбцом (получить максимальное значение конкретного столбца, проиндексированного другим столбцом)

    Почему эксклюзивные эксклюзивные срезы и диапазоны?

    выключить осевую границу для поля полярного matplotlib

    Каков самый быстрый способ для программиста Ruby подобрать Python?

    Выполнять произвольный код python удаленно – это можно сделать?

    Чтение файла CSV UTF8 с помощью Python

    СинтаксисError: недопустимый токен в datetime.datetime (2012,05,22,09,03,41)?

    argparse conflict resolver для опций в подкомандах превращает аргумент ключевого слова в позиционный аргумент

    Наследование Python: TypeError: объект .__ init __ () не принимает параметров

    Zipline: использование pandas-datareader для подачи данных в Google Finance для нефинансовых финансовых рынков

    Проблемы с использованием subprocess.call () в Python 2.7.2 на Windows

    Ошибка при экспорте с помощью pydub – как установить mp3-кодеки для pydub?

    Рекурсивный обход графа: как генерировать и возвращать все пути?

    Python - лучший язык программирования в мире.